<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://wiki.ocetechnology.com/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Okhoruzhyy</id>
	<title>wiki - User contributions [en-gb]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.ocetechnology.com/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Okhoruzhyy"/>
	<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php/Special:Contributions/Okhoruzhyy"/>
	<updated>2026-10-22T08:30:29Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.36.1</generator>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=DMON_SOC_support&amp;diff=1493</id>
		<title>DMON SOC support</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=DMON_SOC_support&amp;diff=1493"/>
		<updated>2022-05-10T10:46:04Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* DMON PROM Builder Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= ARM support =&lt;br /&gt;
&lt;br /&gt;
DMON v2 integrates the Segger J Link debug link and adds proof of concept support for a single ARM target - STM32L152VB. The Segger J Link supports a huge number of processors, see https://www.segger.com/jlink_supported_devices.html . DMON2 customers can request support for additional ARM devices.&lt;br /&gt;
&lt;br /&gt;
The following command line options must be passed to DMON for this mode:&lt;br /&gt;
&lt;br /&gt;
:'''''-arm''''' Start DMON in ARM mode and load ARM specific commands&lt;br /&gt;
&lt;br /&gt;
:'''''-segger''''' Use Segger J-Link&lt;br /&gt;
&lt;br /&gt;
:'''''-device STM32L152VB'''''	Specify the device for Segger &lt;br /&gt;
&lt;br /&gt;
:'''''-swd''''' Use the Serial Wire Debug interface (SWD). If not specified then Segger will use JTAG to communicate with the target. The use of SWD is optional but recommended.&lt;br /&gt;
&lt;br /&gt;
Some optional switches:&lt;br /&gt;
&lt;br /&gt;
:'''''-svd [file location]''''' Set svd file to use for device initialisation.&lt;br /&gt;
&lt;br /&gt;
:'''''-rtt''''' Enable rtterminal command. Read target output to DMON console.&lt;br /&gt;
&lt;br /&gt;
:'''''-jlinkscript [file location]''''' Set jlink script file.&lt;br /&gt;
&lt;br /&gt;
:'''''-setresettype [reset type]''''' Set reset type, default type is JLINKARM_CM3_RESET_TYPE_NORMAL.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When DMON is started with the appropriate ARM switches information about the link discovered is displayed (as below).&lt;br /&gt;
&lt;br /&gt;
The device configuration for the ARM target is read from an ARM CSMIS SVD file which describes the peripheral devices and their registers. In this version this SVD file is included as part of the built DMON and only this file is loaded and used.&lt;br /&gt;
The output below shows device and peripheral information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:gui-armstart.gif]]&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Name of the device                STM32L152VB&lt;br /&gt;
Core id of the device             0x4BA00477&lt;br /&gt;
CPU core                          CORTEX_M3&lt;br /&gt;
Device manufacturer               ST&lt;br /&gt;
Start address of flash area       0x08000000&lt;br /&gt;
Start address of RAM area         0x20000000&lt;br /&gt;
0=Little, 1=Big, 2=Both           0&lt;br /&gt;
Total flash size in bytes         132 KB&lt;br /&gt;
Total RAM size in bytes           16 KB&lt;br /&gt;
Flash regions :&lt;br /&gt;
  Start Address:                  0x08000000 &lt;br /&gt;
  Size:                           128 KB&lt;br /&gt;
  Start Address:                  0x08080000 &lt;br /&gt;
  Size:                           4 KB&lt;br /&gt;
RAM regions :&lt;br /&gt;
  Start Address :                 0x20000000 &lt;br /&gt;
  Size :                          16 KB&lt;br /&gt;
&lt;br /&gt;
OEM : IAR&lt;br /&gt;
Target Voltage = 3.338 V&lt;br /&gt;
&lt;br /&gt;
Connected with SWD&lt;br /&gt;
&lt;br /&gt;
Identified ::: Cortex-M3 core&lt;br /&gt;
Target interface speed: 1000 kHz&lt;br /&gt;
Peripheral Devices:&lt;br /&gt;
C_ADC     Common ADC registers                                        N/A  &lt;br /&gt;
COMP      Comparators                                                 N/A  &lt;br /&gt;
CRC       CRC calculation unit                                        N/A  &lt;br /&gt;
DAC       Digital-to-analog converter                                 N/A  &lt;br /&gt;
DMA1      Direct memory access controller                             N/A  &lt;br /&gt;
EXTI      External interrupt/event controller                         N/A  &lt;br /&gt;
Flash     Flash                                                       N/A  &lt;br /&gt;
GPIOA     General-purpose I/Os                                        N/A  &lt;br /&gt;
GPIOB     General-purpose I/Os                                        N/A  &lt;br /&gt;
GPIOC     General-purpose I/Os                                        N/A  &lt;br /&gt;
GPIOD     General-purpose I/Os                                        N/A  &lt;br /&gt;
GPIOE     General-purpose I/Os                                        N/A  &lt;br /&gt;
GPIOH     General-purpose I/Os                                        N/A  &lt;br /&gt;
I2C1      Inter-integrated circuit                                    N/A  &lt;br /&gt;
I2C2      Inter-integrated circuit                                    N/A  &lt;br /&gt;
IWDG      Independent watchdog                                        N/A  &lt;br /&gt;
LCD       Liquid crystal display controller                           N/A  &lt;br /&gt;
PWR       Power control                                               N/A  &lt;br /&gt;
RCC       Reset and clock control                                     N/A  &lt;br /&gt;
RI        Routing interface                                           N/A  &lt;br /&gt;
RTC       Real-time clock                                             N/A  &lt;br /&gt;
SPI1      Serial peripheral interface                                 N/A  &lt;br /&gt;
SPI2      Serial peripheral interface                                 N/A  &lt;br /&gt;
SYSCFG    System configuration controller                             N/A  &lt;br /&gt;
TIM10     General-purpose timers                                      N/A  &lt;br /&gt;
TIM11     General-purpose timers                                      N/A  &lt;br /&gt;
TIM2      General-purpose timers                                      N/A  &lt;br /&gt;
TIM3      General-purpose timers                                      N/A  &lt;br /&gt;
TIM4      General-purpose timers                                      N/A  &lt;br /&gt;
TIM6      Basic timers                                                N/A  &lt;br /&gt;
TIM7      Basic timers                                                N/A  &lt;br /&gt;
TIM9      General-purpose timers                                      N/A  &lt;br /&gt;
USART1    Universal synchronous asynchronous receiver transmitter     N/A  &lt;br /&gt;
USART2    Universal synchronous asynchronous receiver transmitter     N/A  &lt;br /&gt;
USART3    Universal synchronous asynchronous receiver transmitter     N/A  &lt;br /&gt;
USB       Universal serial bus full-speed device interface            N/A  &lt;br /&gt;
USB_SRAM  Universal serial bus full-speed device interface            N/A  &lt;br /&gt;
WWDG      Window watchdog                                             N/A  &lt;br /&gt;
ADC       Analog-to-digital converter                                 N/A  &lt;br /&gt;
NVIC      Nested Vectored Interrupt Controller                        N/A  &lt;br /&gt;
DBG       Debug support                                               N/A  &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The SVD is used create objects for each peripheral device, to build a layout diagram for the SoC with the same functionality as for SPARC devices, and a widget with a drop down list of the registers for each peripheral.&lt;br /&gt;
There is also an object and widget for the CPU (see below).&lt;br /&gt;
&lt;br /&gt;
[[File:gui-armlayout.gif|600px]]&lt;br /&gt;
&lt;br /&gt;
[[File:gui-armregister.gif|600px]]&lt;br /&gt;
&lt;br /&gt;
On-chip IP blocks can be selected and their registers viewed and modified through the GUI.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== ARM supported DMON commands ==&lt;br /&gt;
&lt;br /&gt;
When in ARM mode the console supports the following commands:&lt;br /&gt;
&lt;br /&gt;
{| class=	wikitable			&lt;br /&gt;
! style=	font-weight : bold; |	Command	||	Description&lt;br /&gt;
|-				&lt;br /&gt;
|		about	||	Display information about DMON version&lt;br /&gt;
|-				&lt;br /&gt;
|		breakh &amp;lt;addr&amp;amp;#124;symbol&amp;gt;	||	Display breakpoints or add hardware breakpoint&lt;br /&gt;
|-				&lt;br /&gt;
|		breaks &amp;lt;addr&amp;amp;#124;symbol&amp;gt;	||	Display or add software breakpoint&lt;br /&gt;
|-				&lt;br /&gt;
|		clear &amp;lt;num&amp;amp;#124;address&amp;gt;	||	Delete all breakpoints or breakpoint at number or address&lt;br /&gt;
|-				&lt;br /&gt;
|		cls	||	Clear console&lt;br /&gt;
|-				&lt;br /&gt;
|		code &amp;lt;addr&amp;amp;#124;PC&amp;gt; &amp;lt;length&amp;gt; &amp;lt;mode&amp;gt;	||	Disassemble &amp;lt;length&amp;gt; instructions starting at &amp;lt;address&amp;gt; or current PC using &amp;lt;mode&amp;gt; (ARM or Thumb).Default mode is the currently set mode, this will normally correctly recognise whether the instruction is ARM or Thumb.&lt;br /&gt;
|-				&lt;br /&gt;
|		continue	||	Continue execution&lt;br /&gt;
|-&lt;br /&gt;
|               cwd &amp;lt;path&amp;gt;      ||     Display or change working directory&lt;br /&gt;
|-				&lt;br /&gt;
|		datamon load [filename]	||	Load a DataSet from an xml file&lt;br /&gt;
|-				&lt;br /&gt;
|		datamon save [filename]	||	Save the current DataSet to an xml file&lt;br /&gt;
|-				&lt;br /&gt;
|		datamon start	||	Validate the current DataSet if successful, start monitoring&lt;br /&gt;
|-				&lt;br /&gt;
|		datamon stop	||	Stop monitoring&lt;br /&gt;
|-				&lt;br /&gt;
|		datamon xsd [filename]	||	Save schema for DataSet to the specified file&lt;br /&gt;
|-				&lt;br /&gt;
|		devreg	||	List available devices&lt;br /&gt;
|-				&lt;br /&gt;
|		devreg &amp;lt;name&amp;gt;	||	Display registers in &amp;lt;name&amp;gt;&lt;br /&gt;
|-				&lt;br /&gt;
|		devreg &amp;lt;name&amp;gt; &amp;lt;regname&amp;gt;	||	Display register detail for &amp;lt;regname&amp;gt; in &amp;lt;name&amp;gt;&lt;br /&gt;
|-				&lt;br /&gt;
|		devreg &amp;lt;name&amp;gt; &amp;lt;regname&amp;gt; &amp;lt;value&amp;gt;	||	Write &amp;lt;value&amp;gt; to &amp;lt;regname&amp;gt; in &amp;lt;name&amp;gt;&lt;br /&gt;
|-				&lt;br /&gt;
|		devreg &amp;lt;name&amp;gt; list	||	List register names in &amp;lt;name&amp;gt;&lt;br /&gt;
|-				&lt;br /&gt;
|		dmon	||	Use only DMON commands. Ignored if already in DMON mode&lt;br /&gt;
|-				&lt;br /&gt;
|		echo [string]	||	Display string in the console (and log file if active)&lt;br /&gt;
|-				&lt;br /&gt;
|		examine [addr] &amp;lt;length&amp;gt;	||	Display memory&lt;br /&gt;
|-				&lt;br /&gt;
|		exec [command]	||	Execute shell command in OS&lt;br /&gt;
|-&lt;br /&gt;
|               find [label]    ||      Finds all occurrences of this label&lt;br /&gt;
|-				&lt;br /&gt;
|		flash erase	||	Erase flash device&lt;br /&gt;
|-				&lt;br /&gt;
|		font	||	Show current font&lt;br /&gt;
|-				&lt;br /&gt;
|		font list	||	List system fonts&lt;br /&gt;
|-				&lt;br /&gt;
|		font reset	||	Reset the font to the default&lt;br /&gt;
|-				&lt;br /&gt;
|		font set [value]	||	Set font&lt;br /&gt;
|-				&lt;br /&gt;
|		gb2312	||	Use GB2312 character set for displaying memory data&lt;br /&gt;
|-				&lt;br /&gt;
|		getb [address] &amp;lt;count&amp;gt;	||	Returns a byte or array of &amp;lt;count&amp;gt; bytes in the command response (for scripting in Tcl)&lt;br /&gt;
|-				&lt;br /&gt;
|		getstate	||	Returns 1 if an application is running on the target, 0 otherwise. (for scripting in Tcl)&lt;br /&gt;
|-				&lt;br /&gt;
|		getw [address] &amp;lt;count&amp;gt;	||	Returns a word or array of &amp;lt;count&amp;gt; words in the command response&lt;br /&gt;
|-				&lt;br /&gt;
|		halt	||	Stop program on board&lt;br /&gt;
|-				&lt;br /&gt;
|		help &amp;lt;command&amp;gt;	||	Display commands or command&lt;br /&gt;
|-&lt;br /&gt;
|               iminfo &amp;lt;name&amp;gt;  ||       Show metadata for this image or for all known images&lt;br /&gt;
|-	&lt;br /&gt;
|               iminfodel      ||       Delete all image information from DMON (target memory not changed)&lt;br /&gt;
|-			&lt;br /&gt;
|		info dev	||	List devices available for info dev command&lt;br /&gt;
|-				&lt;br /&gt;
|		info dev &amp;lt;name&amp;gt;	||	Display information for device &amp;lt;name&amp;gt;&lt;br /&gt;
|-				&lt;br /&gt;
|		info sys	||	Display basic system information&lt;br /&gt;
|-&lt;br /&gt;
|               linfo           ||      Print License Key Information&lt;br /&gt;
|-&lt;br /&gt;
|               load &amp;lt;addr&amp;gt;[file]   ||  Load file to target; for BIN file, start at &amp;lt;addr&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|               load [file]         ||  Load file to target memory&lt;br /&gt;
|-				&lt;br /&gt;
|		log [file_name]	||	Open log file or create new and output some system information&lt;br /&gt;
|-				&lt;br /&gt;
|		loglevel [level]	||	Set internal logging to level. Possible levels [verbose&amp;amp;#124;restore&amp;amp;#124;info&amp;amp;#124;warn&amp;amp;#124;error]&lt;br /&gt;
|-				&lt;br /&gt;
|		logoff	||	Stop output to file&lt;br /&gt;
|-				&lt;br /&gt;
|		lookup [hex value]	||	Show the ELF symbol matching the hex address&lt;br /&gt;
|-				&lt;br /&gt;
|		lookup [symbol or expression]	||	Show the value of the symbol (internal or ELF)&lt;br /&gt;
|-&lt;br /&gt;
|               mon [addr][bit][script]            ||   Runs script everytime bit is set (DMON unset's this if bit is set)&lt;br /&gt;
|- &lt;br /&gt;
|               mon [addr][script]                 ||   Runs script everytime addr value changes&lt;br /&gt;
|-&lt;br /&gt;
|               mon [pen][clr][msk][b][scrp]       ||   Runs script everytime bit(b) at pending field is set (DMON unset's this through clr address)&lt;br /&gt;
|-&lt;br /&gt;
|               mon stop                           ||   Stops IRQ monitoring if running&lt;br /&gt;
|-				&lt;br /&gt;
|		pause -1	||	Pause script until processor stops&lt;br /&gt;
|-				&lt;br /&gt;
|		pause [duration in ms]	||	Pause script until duration has elapsed or processor stops&lt;br /&gt;
|-				&lt;br /&gt;
|		precont [filename]	||	Append a script to the user scripts executed before continuing/stepping a program&lt;br /&gt;
|-				&lt;br /&gt;
|		precont insert [index] [filename]	|| Insert a script at [index] in the user scripts executed before continuing/stepping a program&lt;br /&gt;
|-				&lt;br /&gt;
|		precont list	||	List the user scripts executed before continuing/stepping a program&lt;br /&gt;
|-				&lt;br /&gt;
|		precont remove [index&amp;amp;#124;all]		||   Remove the script at [index] in the user scripts or all scripts executed before continuing/stepping a program&lt;br /&gt;
|-&lt;br /&gt;
|               preproc [file]                          ||   Append a script to be executed before TCF Debugging Process starts&lt;br /&gt;
|- &lt;br /&gt;
|               preproc insert [index][filename]        ||   Insert a script at [index] in the TCF scripts&lt;br /&gt;
|-&lt;br /&gt;
|               preproc list                            ||   List all TCF PRE Process scripts&lt;br /&gt;
|-&lt;br /&gt;
|               preproc remove [index&amp;amp;#124;all]         ||   Remove the script at [index] in the TCF scripts or all scripts&lt;br /&gt;
|-				&lt;br /&gt;
|		prerun [filename]	||	Append a script to the user scripts executed before starting a program&lt;br /&gt;
|-				&lt;br /&gt;
|		prerun insert [index] [filename]	||	Insert a script at [index] in the user scripts executed before starting a program&lt;br /&gt;
|-				&lt;br /&gt;
|		prerun list	||	List the user scripts executed before starting a program&lt;br /&gt;
|-				&lt;br /&gt;
|		prerun remove [index&amp;amp;#124;all]	||	Remove the script at [index] in the user scripts or all scripts executed before starting a program&lt;br /&gt;
|-				&lt;br /&gt;
|		printreg	||	Display system registers&lt;br /&gt;
|-				&lt;br /&gt;
|		python	||	Interpret command input as Python commands. Ignored if in Python mode&lt;br /&gt;
|-				&lt;br /&gt;
|		quit	||	Exit DMON&lt;br /&gt;
|-				&lt;br /&gt;
|		reg	||	Show values for all available CPU registers&lt;br /&gt;
|-				&lt;br /&gt;
|		reg &amp;lt;name&amp;gt;	||	Show register named&lt;br /&gt;
|-				&lt;br /&gt;
|		reg &amp;lt;name&amp;gt; &amp;lt;value&amp;gt;	||	Write value to register named&lt;br /&gt;
|-				&lt;br /&gt;
|		reg show	||	Show available register names&lt;br /&gt;
|-&lt;br /&gt;
|               rtterminal [disable&amp;amp;#124;enable] ||  Enable/disable RTT output to the console(printf)&lt;br /&gt;
|-				&lt;br /&gt;
|		run &amp;lt;pc&amp;gt;	||	Start the CPU from &amp;lt;pc&amp;gt;&lt;br /&gt;
|-				&lt;br /&gt;
|		runscript [filename]	||	Set the user script executed during program execution&lt;br /&gt;
|-				&lt;br /&gt;
|		runscript list	||	List the user script executed during program execution&lt;br /&gt;
|-				&lt;br /&gt;
|		runscript remove	||	Clear the user script executed during program execution&lt;br /&gt;
|-				&lt;br /&gt;
|		save [addr] [addr] [file] &amp;lt;bin&amp;gt;	||	Dump target memory to file in srecord (or binary) format&lt;br /&gt;
|-				&lt;br /&gt;
|		script [file_name]	||	Execute a batch file of DMON commands&lt;br /&gt;
|-				&lt;br /&gt;
|		setv [label] [expression]	||	Sets a DMON label to have a 64 bit integer value&lt;br /&gt;
|-				&lt;br /&gt;
|		shell	||	In a startup script activate the language specified by command line option. Otherwise, display the langauge in use.&lt;br /&gt;
|-&lt;br /&gt;
|               show [symbol]   || Displays value associated with a user defined label, or a list of all user defined symbols&lt;br /&gt;
|-&lt;br /&gt;
|               stack &amp;lt;value&amp;gt;   || Display stack pointer or change initial value to cpu/cpuall&lt;br /&gt;
|-				&lt;br /&gt;
|		step &amp;lt;n&amp;gt;	||	Single step one or &amp;lt;n&amp;gt; times&lt;br /&gt;
|-				&lt;br /&gt;
|		stop	||	Invoked on CTRL-C. Abort DMON command,stop program on board&lt;br /&gt;
|-				&lt;br /&gt;
|		symbols &amp;lt;file&amp;gt;	||	Show/load symbols&lt;br /&gt;
|-				&lt;br /&gt;
|		tcl	||	Interpret command input as Tcl commands. Ignored if in Tcl mode&lt;br /&gt;
|-				&lt;br /&gt;
|		utf8	||	Use UTF-8 character set for displaying memory and UART data&lt;br /&gt;
|-				&lt;br /&gt;
|		watch &amp;lt;addr&amp;amp;#124;symbol&amp;gt;	||	Display all breakpoint or add data watchpoint on read or write&lt;br /&gt;
|-				&lt;br /&gt;
|		watchr &amp;lt;addr&amp;amp;#124;symbol&amp;gt;	||	Display all breakpoint or add data watchpoint on read&lt;br /&gt;
|-				&lt;br /&gt;
|		watchw &amp;lt;addr&amp;amp;#124;symbol&amp;gt;	||	Display all breakpoint or add data watchpoint on write&lt;br /&gt;
|-				&lt;br /&gt;
|		write [addr] [data] &amp;lt;number words&amp;gt;	||	Write one word of data to &amp;quot;number words&amp;quot; starting from addr &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ARM specific commands ==&lt;br /&gt;
 &lt;br /&gt;
The devreg commands are specific to ARM peripherals, and display or modify the registers in a specified peripheral:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
DMON &amp;gt; devreg&lt;br /&gt;
&lt;br /&gt;
Available devices:&lt;br /&gt;
ADC            COMP           CRC            C_ADC          &lt;br /&gt;
DAC            DBG            DMA1           EXTI           &lt;br /&gt;
FLASH          GPIOA          GPIOB          GPIOC          &lt;br /&gt;
GPIOD          GPIOE          GPIOH          I2C1           &lt;br /&gt;
I2C2           IWDG           LCD            NVIC           &lt;br /&gt;
PWR            RCC            RI             RTC            &lt;br /&gt;
SPI1           SPI2           SYSCFG         TIM10          &lt;br /&gt;
TIM11          TIM2           TIM3           TIM4           &lt;br /&gt;
TIM6           TIM7           TIM9           USART1         &lt;br /&gt;
USART2         USART3         USB            USB_SRAM       &lt;br /&gt;
WWDG           &lt;br /&gt;
&lt;br /&gt;
DMON &amp;gt; devreg gpioe&lt;br /&gt;
&lt;br /&gt;
GPIOE&lt;br /&gt;
 0x40021000   GPIO port mode (MODER)                   0x00500000 &lt;br /&gt;
 0x40021004   GPIO port output type (OTYPER)           0x00000000 &lt;br /&gt;
 0x40021008   GPIO port output speed (OSPEEDER)        0x00f00000 &lt;br /&gt;
 0x4002100c   GPIO port pull-up/pull-down (PUPDR)      0x00000000 &lt;br /&gt;
 0x40021010   GPIO port input data (IDR)               0x00001000 &lt;br /&gt;
 0x40021014   GPIO port output data (ODR)              0x00000000 &lt;br /&gt;
 0x40021018   GPIO port bit set/reset (BSRR)           0x00000000 &lt;br /&gt;
 0x4002101c   GPIO port configuration lock (LCKR)      0x00000000 &lt;br /&gt;
 0x40021020   AFRL (AFRL)                              0x00000000 &lt;br /&gt;
 0x40021024   GPIO alternate function high (AFRH)      0x00000000 &lt;br /&gt;
&lt;br /&gt;
DMON &amp;gt; devreg gpioe odr 0xffffffff&lt;br /&gt;
&lt;br /&gt;
Wrote value 0xffffffff to odr&lt;br /&gt;
&lt;br /&gt;
DMON &amp;gt; devreg gpioe&lt;br /&gt;
&lt;br /&gt;
GPIOE&lt;br /&gt;
 0x40021000   GPIO port mode (MODER)                   0x00500000 &lt;br /&gt;
 0x40021004   GPIO port output type (OTYPER)           0x00000000 &lt;br /&gt;
 0x40021008   GPIO port output speed (OSPEEDER)        0x00f00000 &lt;br /&gt;
 0x4002100c   GPIO port pull-up/pull-down (PUPDR)      0x00000000 &lt;br /&gt;
 0x40021010   GPIO port input data (IDR)               0x00001c00 &lt;br /&gt;
 0x40021014   GPIO port output data (ODR)              0x0000ffff &lt;br /&gt;
 0x40021018   GPIO port bit set/reset (BSRR)           0x00000000 &lt;br /&gt;
 0x4002101c   GPIO port configuration lock (LCKR)      0x00000000 &lt;br /&gt;
 0x40021020   AFRL (AFRL)                              0x00000000 &lt;br /&gt;
 0x40021024   GPIO alternate function high (AFRH)      0x00000000&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= AGGA-4 Support =&lt;br /&gt;
&lt;br /&gt;
== AGGA-4 hardware ==&lt;br /&gt;
&lt;br /&gt;
The AGGA-4 (Advanced GPS/GALILEO ASIC) is a radiation tolerant GNSS baseband ASIC capable of processing the modernized GPS and Galileo Signals. Due to its flexibility it is also able to process not only GPS and Galileo but also other GNSS systems like Glonass, Compass, etc. AGGA-4 also incorporates the processor, the communication interfaces and other support functions (e.g. FFT, CRC) inside the ASIC which simplifies the GNSS receiver board design.&lt;br /&gt;
&lt;br /&gt;
The functional blocks are shown in the diagram below.&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-BlockDiagram1.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The GNSS Core (shown below) consists of 4 Input Modules (IM), one Power Level Detector (PLD) Module, two Beam Forming (DBF) Modules, a Time Base Generator (TBG), an Antenna Switch Controller (ASC) and 36 channels.&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-BlockDiagram2.png|600px]]&lt;br /&gt;
&lt;br /&gt;
DMON supports the functional blocks on the AGGA-4 and the specific features below:&lt;br /&gt;
&lt;br /&gt;
#System Visualisation&lt;br /&gt;
##Devices present and their state&lt;br /&gt;
##Register details/modify&lt;br /&gt;
#GNSS&lt;br /&gt;
##Configuration Blocks Display and Modify&lt;br /&gt;
##Interrupt Configuration&lt;br /&gt;
##Power Level&lt;br /&gt;
#Channel Configurations&lt;br /&gt;
##Overall display&lt;br /&gt;
##Set, Copy, Modify, Save and Load&lt;br /&gt;
##Dump observables to file&lt;br /&gt;
#FFT&lt;br /&gt;
#CRC&lt;br /&gt;
&lt;br /&gt;
See below some example screenshots from the tool.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Main AGGA4 console ==&lt;br /&gt;
&lt;br /&gt;
GNSS on AGGA4 has a lot of Configuration Registers. DMON identifies GNSS as AGGA4_GNSS_FE/CHS dummy device and logically AGGA4_GNSS_FR_END device (IM0, IM1, IM2, IM3 and PLD) and AGGA4_GNSS_CHS device (Channel Matrix, IC, Channels).&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-Console.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== Power Level Detector window ==&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-PLD.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== Power Level Detector chart ==&lt;br /&gt;
DMON reads PLD Accumulation Registers and Displays as Bar Chart&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-PLDchart.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== Channel Matrix Window ==&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-CHmatrix.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== Input Module window ==&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-IM.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== Channel Control window ==&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-CHcontrol1.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== Channel Final Down Converter window ==&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-FDC.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== Channel Code Delay Line Unit window ==&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-CDL.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== Channel Code Generator Unit window ==&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-CGU.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== Channel Correlator Unit window ==&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-Correlator.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== Channel Aiding Unit window ==&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-CHaiding.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== Channel GNSS DMA window ==&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-GNSSdma.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== Channel Status window ==&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-CHstatus.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== Commands ==&lt;br /&gt;
&lt;br /&gt;
The sections below describe the AGGA-4 commands. The table below is a summary of these commands.&lt;br /&gt;
&lt;br /&gt;
{| class=	wikitable		&lt;br /&gt;
! style=	font-weight	: bold; | Command	&lt;br /&gt;
! style=	font-weight	: bold; | Description	&lt;br /&gt;
|-			&lt;br /&gt;
|	gnss copy &amp;lt;nomem&amp;gt;[ch[#]..ch[n]/all] || copy config from ch# to other space separated channels/all if &amp;lt;nomem&amp;gt; used the RAM code not copied&lt;br /&gt;
|-			&lt;br /&gt;
|	gnss [save/load] ch# file || Save/load Channel Configurations to File as xml&lt;br /&gt;
|-			&lt;br /&gt;
|	gnss dump [start/stop] ch# file  ||  Start/Stop dumping of Channel Observables to File&lt;br /&gt;
|-			&lt;br /&gt;
|	gnss dump reset ch#          ||      	Reset dumping of Channel Observables to initial state&lt;br /&gt;
|-			&lt;br /&gt;
|	gnss printreg ch [#] [RegName]   ||  Display Registers/Register for GNSS Channel [number]&lt;br /&gt;
|-			&lt;br /&gt;
|	gnss printreg cm [RegName]   ||     Display Registers/Register for GNSS Channel Matrix&lt;br /&gt;
|-			&lt;br /&gt;
|	gnss printreg ic [RegName]       ||  	Display Registers/Register for GNSS Interrupt Controller&lt;br /&gt;
|-			&lt;br /&gt;
|	gnss printreg im [#][RegName]  ||    Display Registers/Register for GNSS Input Module&lt;br /&gt;
|-			&lt;br /&gt;
|	gnss printreg pld [RegName]    ||    Display Registers/Register for GNSS POWER LEVEL DETECTOR&lt;br /&gt;
|-			&lt;br /&gt;
|	gnss setreg ch [#] [RegName/FieldName][val] ||	Set Register/Bitfield for GNSS Channel [number]    &lt;br /&gt;
|-			&lt;br /&gt;
|	gnss setreg cm [RegName/FieldName][val]     ||      Set Register/Bitfield for GNSS Channel Matrix&lt;br /&gt;
|-			&lt;br /&gt;
|	gnss setreg ic [RegName/FieldName][val]	|| Set Register/Bitfield for GNSS Interrupt Controller&lt;br /&gt;
|-			&lt;br /&gt;
|	gnss setreg im [#][RegName/FieldName][val] ||	Set Register/Bitfield for GNSS Input Module&lt;br /&gt;
|-			&lt;br /&gt;
|	gnss setreg pld [RegName/FieldName][val]	|| Set Register/Bitfield for GNSS PLD           &lt;br /&gt;
|-			&lt;br /&gt;
|	gnss slave [ch[#] ch[n]/all]    ||   Slave channel/channels from to/all to previous Channel&lt;br /&gt;
|-			&lt;br /&gt;
|	fft &amp;lt;display&amp;gt;         ||       Periodically checks FFT_Done bit and display results, &amp;lt;display&amp;gt; opens up graph panel&lt;br /&gt;
|-			&lt;br /&gt;
|	fft [file in] &amp;lt;optional&amp;gt; || Processes input file in pairs of 128, if output file is omitted then results will be stored .out.csv added to end of [file in]. Possible optional arguments are &amp;lt;file out&amp;gt; &amp;lt;nohex,onlyhex&amp;gt;&lt;br /&gt;
|-			&lt;br /&gt;
|	fft stop              ||                       Stops periodically polling&lt;br /&gt;
|-			&lt;br /&gt;
|	crc alias [name][poly][init] &amp;lt;opt&amp;gt;   ||  Creates new alias, option arguments are &amp;lt;xor&amp;gt; &amp;lt;revdata&amp;gt; &amp;lt;revrslt&amp;gt;&lt;br /&gt;
|-			&lt;br /&gt;
|	crc alias display          ||   Display list of aliases in current DMON session&lt;br /&gt;
|-			&lt;br /&gt;
|	crc calculate [bin] &amp;lt;addr&amp;gt;         ||  Calculates crc of bin file, addr argument sets starting address for file&lt;br /&gt;
|-			&lt;br /&gt;
|	crc calculate [elffile] &amp;lt;sections&amp;gt;   ||    Calculates crc of elf file, section argument allows calculation only on that section&lt;br /&gt;
|-			&lt;br /&gt;
|	crc calculate [srec]            ||                   Calculates crc of srec file&lt;br /&gt;
|-			&lt;br /&gt;
|	crc calculate [start][end]&amp;lt;init&amp;gt; || Calculates crc of a range of address, if init value is specified then that value will be written to CRCLFSR register before beginning.&lt;br /&gt;
|-			&lt;br /&gt;
|	crc init [alias]           ||    Initialises CRC device with values in alias&lt;br /&gt;
|-			&lt;br /&gt;
|	crc init [ploy][init] &amp;lt;opt&amp;gt;       ||      Initialises CRC device, optional arguments are  &amp;lt;xor&amp;gt; &amp;lt;revdata&amp;gt; &amp;lt;revrslt&amp;gt;&lt;br /&gt;
|-			&lt;br /&gt;
|	reset &amp;lt;software/gnss&amp;gt;             ||                Reset system software or gnss software&lt;br /&gt;
|-			&lt;br /&gt;
|	reset set &amp;lt;key&amp;gt; &amp;lt;value&amp;gt;          ||           set the reset key &amp;lt;swen, swex, gnssen, gnssex&amp;gt; with value&lt;br /&gt;
|-			&lt;br /&gt;
|	spwdebug &amp;lt;IP/port&amp;gt; &amp;lt;port&amp;gt;      || Change debug link to SpaceWire port&lt;br /&gt;
|-			&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GNSS commands ===&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; gnss copy nomem ch0 ch1&lt;br /&gt;
 Configurations from Channel 0 were copied to Channel 1 without RAM DATA&lt;br /&gt;
 DMON &amp;gt; gnss copy ch0 ch1 ch2&lt;br /&gt;
 Configurations from Channel 0 were copied to Channel 1 &lt;br /&gt;
 Configurations from Channel 0 were copied to Channel 2&lt;br /&gt;
&lt;br /&gt;
Or Alternatively Copy Dialog Window can be used&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-CHcopy.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The user can select Channel, Configuration Registers and Values for exporting to xml file.  This file can be loaded later for the same Channel or any other.&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; gnss save ch0 MyFile.xml&lt;br /&gt;
 Currently processing XML, please wait&lt;br /&gt;
 Successfully save configuration to C:\Projects\OCE\trunk\dmon_product\com.oce.dmon\MyFile.xml&lt;br /&gt;
 DMON &amp;gt; gnss load ch0 MyFile.xml&lt;br /&gt;
 Processing XML&lt;br /&gt;
 Initialising Registers&lt;br /&gt;
 Successfully initialised registers&lt;br /&gt;
&lt;br /&gt;
Dialog to Save Channel configurations to xml file below.&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-CHsave.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dialog to Save GNSS to xml file below.&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-CHexport.png]]&lt;br /&gt;
&lt;br /&gt;
Dialog to Save AGGA4 specific registers to xml file below.&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-CHexport1.png]]&lt;br /&gt;
&lt;br /&gt;
Dialog to select xml configuration file to be imported below.&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-CHimport.png]]&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; gnss printreg ch 0&lt;br /&gt;
 AGGA4 GNSS CHANNEL 0 Registers&lt;br /&gt;
  0xa0000000   channelctrl                              0x00000000 &lt;br /&gt;
  0xa0000004   carrswfreq                               0x00000000 &lt;br /&gt;
  0xa0000008   carrswshift                              0x00000000 &lt;br /&gt;
  0xa000000c   codeswfreq            ….&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; gnss printreg ch 0 channelctrl&lt;br /&gt;
 GNSS Channel #0 Reg :: channelctrl =  0x00000000&lt;br /&gt;
 Register Contents                       : 0x00000000&lt;br /&gt;
 [ 0, 4]:InputSel                              : first bypass of DBF0 (IM 0) &lt;br /&gt;
    [ 5]:CarrSel                                : Local&lt;br /&gt;
    [ 6]:CodeSel                                : Local&lt;br /&gt;
    [ 7]:IntEpochSel                         : Local&lt;br /&gt;
    [ 8]:TimeBaseSel                        : Local&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; gnss printreg cm&lt;br /&gt;
 AGGA4 GNSS CHANNEL MATRIX  Registers :&lt;br /&gt;
  0xa0240000   chactivation0                            0x00000001 &lt;br /&gt;
  0xa0240004   chactivation1                            0x00000000 &lt;br /&gt;
  0xa0240008   dbfinputsel                              0x00000000 &lt;br /&gt;
  0xa024000c   epochclkdiv       …&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; gnss printreg cm  chactivation0&lt;br /&gt;
 &lt;br /&gt;
 GNSS Channel Matrix Reg :: chactivation0 =  0x00000001&lt;br /&gt;
 Register Contents                       : 0x00000001&lt;br /&gt;
    [ 0]:Channel_0                              : enabled&lt;br /&gt;
    [ 1]:Channel_1                              : disabled&lt;br /&gt;
    [ 2]:Channel_2                              : disabled&lt;br /&gt;
    [ 3]:Channel_3                              : disabled&lt;br /&gt;
    [ 4]:Channel_4                              : disabled&lt;br /&gt;
    [ 5]:Channel_5                              : disabled&lt;br /&gt;
    [ 6]:Channel_6   ….&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; gnss printreg ic &lt;br /&gt;
 &lt;br /&gt;
 AGGA4 GNSS Interrupt Controller Registers :&lt;br /&gt;
  0xa02c0000   gic_mask0                            0x00000000 &lt;br /&gt;
  0xa02c0004   gic_mask1                            0x00000000 &lt;br /&gt;
  0xa02c0008   gic_prio0                            0x00000001 &lt;br /&gt;
  0xa02c000c   gic_prio1                            0x00000000 &lt;br /&gt;
  0xa02c0010   gic_pend0                            0x00000000 &lt;br /&gt;
  0xa02c0014   gic_pend1                            0x00000070 &lt;br /&gt;
  0xa02c0018   gic_clear0                           0x00000000 &lt;br /&gt;
  0xa02c001c   gic_clear1                           0x00000000 &lt;br /&gt;
  0xa02c0020   gic_queuelow                         0x0000003f &lt;br /&gt;
  0xa02c0024   gic_queuehigh                        0x0000003f &lt;br /&gt;
  0xa02c0028   gic_queuestatus                      0x00000000&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; gnss printreg ic  gic_mask0&lt;br /&gt;
 &lt;br /&gt;
 GNSS Interrupt Controller Reg :: gic_mask0 =  0x00000000&lt;br /&gt;
 Register Contents                       : 0x00000000&lt;br /&gt;
    [ 0]:Channel_0                              : Pending Register&lt;br /&gt;
    [ 1]:Channel_1                              : Pending Register&lt;br /&gt;
    [ 2]:Channel_2                              : Pending Register&lt;br /&gt;
    [ 3]:Channel_3                              : Pending Register&lt;br /&gt;
    [ 4]:Channel_4                              : Pending Register&lt;br /&gt;
    [ 5]:Channel_5    …&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; gnss printreg im 0&lt;br /&gt;
 &lt;br /&gt;
 AGGA4 GNSS Input Module_0 Registers :&lt;br /&gt;
  0xa0250000   inputmodulectrl                          0x00000000 &lt;br /&gt;
  0xa0250004   ddcmainphaseinc                          0x00000000 &lt;br /&gt;
  0xa0250008   ddcmainfirquantthres                     0x00000000 &lt;br /&gt;
  0xa025000c   ddcauxphaseinc                           0x00000000 &lt;br /&gt;
  0xa0250010   ddcauxfirquantthres                      0x00000000 &lt;br /&gt;
  0xa0250014   dacontrolbitfielddefaultr                0x00000000&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; gnss printreg im 0  inputmodulectrl &lt;br /&gt;
 &lt;br /&gt;
 GNSS Input Module #0 Reg :: inputmodulectrl =  0x00000000&lt;br /&gt;
 Register Contents                       : 0x00000000&lt;br /&gt;
 [ 0, 1]:Mode                                   : Input Format Converter Mode (IFC)&lt;br /&gt;
 [ 2, 3]:IFCFormat                              : Sign/Magnitude&lt;br /&gt;
    [ 4]:DDCMainInSel                           : local&lt;br /&gt;
    [ 5]:DDCAuxInSel                            : local  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; gnss printreg pld&lt;br /&gt;
 &lt;br /&gt;
 AGGA4 GNSS POWER LEVEL DETECTOR Registers :&lt;br /&gt;
  0xa02b0000   pld5iinputsel                            0x00000000 &lt;br /&gt;
  0xa02b0004   pld5ictrl                                0x00000000 &lt;br /&gt;
  0xa02b0008   pldiqinputsel                            0x00000000 &lt;br /&gt;
  0xa02b000c   pldiqpreaccctrl                          0x00000000 &lt;br /&gt;
  0xa02b0010   pldiqctrl                                0x00000000 &lt;br /&gt;
  0xa02b0014   acc5iplusseven                           0x00000000 &lt;br /&gt;
  0xa02b0018   acc5iplusfive                            0x00000000 &lt;br /&gt;
  0xa02b001c   acc5iplusthree      …&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; gnss printreg pld pld5ictrl &lt;br /&gt;
&lt;br /&gt;
 GNSS Power Level Detector Reg :: pld5ictrl =  0x00000000&lt;br /&gt;
 Register Contents                       : 0x00000000&lt;br /&gt;
 [ 0,23]:AccTime                                : 0&lt;br /&gt;
    [24]:SelectTrigger                          : latched after AccTime Samples  &lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; gnss setreg cm chactivation0 0xffffffff&lt;br /&gt;
 &lt;br /&gt;
 Value for Register chactivation0 set to 0xFFFFFFFF&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; gnss setreg cm chactivation0 Channel_0  0x0&lt;br /&gt;
 &lt;br /&gt;
 Value for Register chactivation0 set to 0xFFFFFFFE &lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; gnss slave ch1 &lt;br /&gt;
 &lt;br /&gt;
 Channel 1 was set as Slave&lt;br /&gt;
&lt;br /&gt;
=== FFT commands ===&lt;br /&gt;
&lt;br /&gt;
Creating FFT Task through the gui, start by clicking on the menu Tasks&amp;gt;&amp;gt;Configure Tasks.&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-FFTtasks.png|600px]]&lt;br /&gt;
&lt;br /&gt;
Find FFT and click create task.&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-FFTtasks1.png|600px]]&lt;br /&gt;
&lt;br /&gt;
If you don’t enter an output file, then an output file will be generated in the input file directory with the same filename but suffixed with .csv.&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-FFTconfig.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The output type can be changed to have all (which includes the hex and float values) or just hex or float.&lt;br /&gt;
All is set by default.&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-FFTconfig1.png|600px]]&lt;br /&gt;
&lt;br /&gt;
When the job is running, it will be located in the overview window, when it is done, it will be moved to the history tab. You will be able&lt;br /&gt;
to see the time it took for the task to run as well as the result. You can click on the log icon to open the log window or alternatively clicking on the x icon deletes the task from history.&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-FFTtasks2.png|600px]]&lt;br /&gt;
&lt;br /&gt;
Here is the results from the FFT task, as you can see a csv suffix was added to the output file. As well as the results being displayed in the Inphase and Quad phase Panels you will also notice log information for this task. &lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-FFTresults.png|600px]]&lt;br /&gt;
&lt;br /&gt;
You can also view the fft information via a line or bar graph by issuing the fft display command.&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-FFTline.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''COMMANDS'''&lt;br /&gt;
&lt;br /&gt;
''fft &amp;lt;display&amp;gt;''  Periodically checks FFT_Done bit and display results, &amp;lt;display&amp;gt; opens up graph panel&lt;br /&gt;
&lt;br /&gt;
 DMON  &amp;gt; fft&lt;br /&gt;
 &lt;br /&gt;
 Waiting for Done bit to be set&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''fft [file in] &amp;lt;optional&amp;gt;''   Processes input file in pairs of 128, if output file is omitted then results will be stored .out.csv added to end of [file in]. Possible optional arguments are &amp;lt;file out&amp;gt; &amp;lt;nohex|onlyhex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; fft C: /newline_sep_data_full.txt    C: /newline_data_full_output.txt&lt;br /&gt;
 &lt;br /&gt;
 Starting batch processing for FFT&lt;br /&gt;
 Finished processing Batch Number: 1&lt;br /&gt;
 Finished processing input file\s&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; fft C: /newline_sep_data_full.txt    C: /newline_data_full_output.txt onlyhex&lt;br /&gt;
 Starting batch processing for FFT&lt;br /&gt;
 Finished processing Batch Number: 1&lt;br /&gt;
 Finished processing input file\s&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; fft C: /newline_sep_data_full.txt    C: /newline_data_full_output.txt nohex&lt;br /&gt;
 Starting batch processing for FFT&lt;br /&gt;
 Finished processing Batch Number: 1&lt;br /&gt;
 Finished processing input file\s&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; fft C: /newline_sep_data_fIll.txt    C: /newline_data_fill_output.txt&lt;br /&gt;
 Starting batch processing for FFT&lt;br /&gt;
 Finished processing Batch Number: 1&lt;br /&gt;
 Finished processing Batch Number: 2&lt;br /&gt;
 Finished processing input file\s&lt;br /&gt;
&lt;br /&gt;
''fft stop''   Stops periodically polling&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; fft stop&lt;br /&gt;
 Stopped FFT batch processing&lt;br /&gt;
&lt;br /&gt;
=== CRC commands ===&lt;br /&gt;
&lt;br /&gt;
You can create a CRC task by clicking on CRC in the dropdown menu and clicking create task.  Here you will be able to set the different properties to be used for generating the CRC.&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-CRCconfig.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-CRCtask.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The results window shows what properties you used to generate the CRC as well as the result and log of the crc task.&lt;br /&gt;
&lt;br /&gt;
[[File:AGGA4-CRCresults.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''COMMANDS'''&lt;br /&gt;
&lt;br /&gt;
''crc alias [name][poly][init] &amp;lt;opt&amp;gt;''  Creates new alias, option arguments are &amp;lt;xor&amp;gt; &amp;lt;revdata&amp;gt; &amp;lt;revrslt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; crc alias myAlias 0x3 0x4 0x5 1 1&lt;br /&gt;
 Successfully added myAlias alias&lt;br /&gt;
&lt;br /&gt;
''crc alias display''    Display list of aliases in current DMON session&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; crc alias display&lt;br /&gt;
 Name	Polynum		Init		FinalXOR	RevIn	RevRes&lt;br /&gt;
 crc16	0x0000A001	0x00000000	0x00000000	true	true&lt;br /&gt;
 ccitt	0x00008408	0x0000FFFF	0x00000000	false	false&lt;br /&gt;
 crc32	0xEDB88320	0xFFFFFFFF	0xFFFFFFFF	true	true&lt;br /&gt;
 myAlias	0x00000003	0x00000004	0x00000005	true	true&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''crc calculate [bin] &amp;lt;addr&amp;gt;''      Calculates crc of bin file, addr argument sets starting address for file&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; crc calculate C: /binaryfileAGGA4.bin 0x40000024&lt;br /&gt;
 Binary File &lt;br /&gt;
 Loading file from address: 0x40000024 &lt;br /&gt;
 Wrote bytes        0%&lt;br /&gt;
 Entry point: 0x40000024&lt;br /&gt;
 &lt;br /&gt;
 There are no Sections in this file. Calculating CRC for Loaded file &lt;br /&gt;
 &lt;br /&gt;
 Starting CRC Polling&lt;br /&gt;
 CRC Polling complete&lt;br /&gt;
 Checksum is  : 0xDCC7C62F&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= GR716 Support =&lt;br /&gt;
&lt;br /&gt;
== GR716 Microcontroller ==&lt;br /&gt;
&lt;br /&gt;
DMON supports the GR716 microcontroller from Cobham-Gaisler. This microcontroller features a fault-tolerant LEON3 SPARC V8 processor, communication interfaces and on-chip ADC, DAC, Power-on-Reset, Oscillator, Brown-out detection, LVDS transceivers, regulators to support for single 3.3V supply, ideally suited for space and other high-rel applications. A block diagram of the GR716 is shown below. DMON provides support for all the functional units on the microcontroller. The sections below provide more information on DMON support for some specific functional units of the microcontroller. &lt;br /&gt;
&lt;br /&gt;
[[File:GR716-Architecture.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
Credit: GR716 User Manual Version 1.26&lt;br /&gt;
&lt;br /&gt;
== Startup Options ==&lt;br /&gt;
&lt;br /&gt;
The table below shows GR716 startup options.&lt;br /&gt;
&lt;br /&gt;
{| class=	wikitable		&lt;br /&gt;
! style=	font-weight	: bold; | Command	&lt;br /&gt;
! style=	font-weight	: bold; | Description	&lt;br /&gt;
|-			&lt;br /&gt;
| -iomx    set [configName configName ...] || Set IOMX configurations for Device or Array of Devices (see IO switch matrix section below)&lt;br /&gt;
|-			&lt;br /&gt;
| -grcg or grcg_(index)    [enable&amp;amp;#124;disable][all&amp;amp;#124;bit..bitN] || Enable&amp;amp;#124;Disable all, single bit or array of bits for GRCLKGATE_(DeviceIndex) (see clock gating section below)&lt;br /&gt;
|-			&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Typical startup options used with the GR716 Mini development board are&lt;br /&gt;
&lt;br /&gt;
 '''''-gui'''''&lt;br /&gt;
 '''''-u'''''&lt;br /&gt;
 '''''-baud 230400'''''&lt;br /&gt;
 '''''-iomx set mem_gr716_mini_cfg0'''''&lt;br /&gt;
 '''''-grcg enable 0x4 16'''''&lt;br /&gt;
 '''''-nosram_1'''''&lt;br /&gt;
&lt;br /&gt;
== Layout window ==&lt;br /&gt;
&lt;br /&gt;
DMON represents the GR716 SOC in the layout below. By clicking on a functional block it's IP and register definitions are displayed in separate windows.&lt;br /&gt;
&lt;br /&gt;
[[File:DMON-GR716-Layout.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
== REX support ==&lt;br /&gt;
&lt;br /&gt;
DMON supports the 16 bit REX instruction set.&lt;br /&gt;
&lt;br /&gt;
[[File:RexMainView.png | 800px|Main View]]&lt;br /&gt;
&lt;br /&gt;
DMON Functions View of loaded image (REX functions are marked with (REX))&lt;br /&gt;
&lt;br /&gt;
[[File:RexFunctions.png|800px|Image Functions View]]&lt;br /&gt;
&lt;br /&gt;
Instruction Trace Information&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; inst 40&lt;br /&gt;
 &lt;br /&gt;
 Rex    Time      Address   Instruction                                    Result &lt;br /&gt;
 R   00000008763  3100A170  ld [%i2 + 0x8], %l6 (rld [%i2 + 0x8], %l6)     [0000000C]&lt;br /&gt;
 R   00000008765  3100A174  sub %l6, %i0, %l6 (rsub %i0, %l6)              [00000000]&lt;br /&gt;
 R   00000008766  3100A176  cmp %l6, 0x0 (rcmp %l6, 0x0)                   [00000000]&lt;br /&gt;
 R   00000008767  3100A178  add %i5, %i0, %i5 (radd %i0, %i5)              [3000005A]&lt;br /&gt;
 R   00000008768  3100A17A  sub %i4, %i0, %i4 (rsub %i0, %i4)              [00000000]&lt;br /&gt;
 R   00000008770  3100A17C  st %l6, [%i2 + 0x8] (rst %l6, [%i2 + 0x8])     [3000FEB0][00000000]&lt;br /&gt;
 R   00000008771  3100A180  bne TestContinue_REX_0x31:__sfvwrite_r + 0x238 (rbne 0xffffff32)  [00000000]&lt;br /&gt;
 R   00000008772  3100A182  add %g0, 0x0, %i0 (rset5 0x0, %i0)             [00000000]&lt;br /&gt;
 R   00000008773  3100A184  ret (rretrest)                                 [3100A181]&lt;br /&gt;
 R   00000008774  3100A184  restore %i7, 0x8, %g0 (rretrest)               [31007E07]&lt;br /&gt;
 R   00000008777  31007E06  add %g0, %o0, %i0 (rmov %o0, %i0)              [00000000]&lt;br /&gt;
 R   00000008778  31007E08  ba TestContinue_REX_0x31:__sprint_r + 0x74 (rba 0x48)  [00000000]&lt;br /&gt;
 R   00000008781  31007E50  st %i4, [%i2 + 0x8] (rst %i4, [%i2 + 0x8])     [3000FEB0][00000000]&lt;br /&gt;
 R   00000008783  31007E54  st %i4, [%i2 + 0x4] (rst %i4, [%i2 + 0x4])     [3000FEAC][00000000]&lt;br /&gt;
 R   00000008784  31007E58  ret (rretrest)                                 [31007E55]&lt;br /&gt;
 R   00000008785  31007E58  restore %i7, 0x8, %g0 (rretrest)               [310042AB]&lt;br /&gt;
 R   00000008788  310042AA  cmp %o0, 0x0 (rcmp %o0, 0x0)                   [00000000]&lt;br /&gt;
 R   00000008791  310042AC  bne TestContinue_REX_0x31:_vfprintf_r + 0x29d0 (rbne 0x10)  [00000000]&lt;br /&gt;
 R   00000008792  310042AE  add %g0, 0x0, %i0 (rset5 0x0, %i0)             [00000000]&lt;br /&gt;
 R   00000008793  310042B0  add %g0, 0xffffff24, %i2 (rset21 0xffffff24, %i2)  [FFFFFF24]&lt;br /&gt;
 R   00000008794  310042B4  ld [%fp + %i2], %i1 (rld [%fp + %i2], %i1)     [3000FEAC]&lt;br /&gt;
 R   00000008797  310042B8  st %i0, [%i1 + 0x0] (rst %i0, [%i1])           [3000FEAC][00000000]&lt;br /&gt;
 R   00000008798  310042BC  add %g0, 0xfffffef8, %i0 (rset21 0xfffffef8, %i0)  [FFFFFEF8]&lt;br /&gt;
 R   00000008800  310042C0  ldd [%fp + %i0], %i4 (rldd [%fp + %i0], %i4)   [3000FED4][0000000C]&lt;br /&gt;
 R   00000008801  310042C4  ba TestContinue_REX_0x31:_vfprintf_r + 0x2a24 (rba 0x4e)  [00000000]&lt;br /&gt;
 R   00000008804  31004312  ldub [%l6 + 0xd], %i0 (rldub [%l6 + 0xd], %i0)  [00000089]&lt;br /&gt;
 R   00000008805  31004316  mov 0x40, %i1 (rone 0x6, %i1)                  [00000040]&lt;br /&gt;
 R   00000008806  31004318  and %i1, %i0, %i1 (rand %i0, %i1)              [00000000]&lt;br /&gt;
 R   00000008807  3100431A  cmp %i1, 0x0 (rcmp %i1, 0x0)                   [00000000]&lt;br /&gt;
 R   00000008810  3100431C  bne TestContinue_REX_0x31:_vfprintf_r + 0x2a34 (rbne 0x6)  [00000000]&lt;br /&gt;
 R   00000008811  3100431E  add %g0, %i5, %i0 (rmov %i5, %i0)              [0000000C]&lt;br /&gt;
 R   00000008812  31004320  ret (rretrest)                                 [3100431D]&lt;br /&gt;
 R   00000008813  31004320  restore %i7, 0x8, %g0 (rretrest)               [310018D1]&lt;br /&gt;
 R   00000008816  310018D0  add %g0, %o0, %i0 (rmov %o0, %i0)              [0000000C]&lt;br /&gt;
 R   00000008817  310018D2  ret (rretrest)                                 [310018CF]&lt;br /&gt;
 R   00000008818  310018D2  restore %i7, 0x8, %g0 (rretrest)               [310012D1]&lt;br /&gt;
 R   00000008822  310012D0  st %o0, [%fp - 0xc] (rst %o0, [%fp - 12])      [3000FF94][0000000C]&lt;br /&gt;
 R   00000008823  310012D4  call TestContinue_REX_0x31:secondHello (call TestContinue_REX_0x31:secondHello)  [310012D1]&lt;br /&gt;
     00000008825  31001278  saverex %sp, %i0, %sp                          [3000FED0]&lt;br /&gt;
 R   00000008826  3100127C  ta 0x1 (rset32 TestContinue_REX_0x31:watchData, %i0)  [TRAPPED ]&lt;br /&gt;
&lt;br /&gt;
REX Dissembled Instructions&lt;br /&gt;
&lt;br /&gt;
 DMON &amp;gt; coderex secondHello&lt;br /&gt;
 &lt;br /&gt;
 Address         hex               dis&lt;br /&gt;
 0x31001278      9DE39F98          saverex %sp, %i0, %sp&lt;br /&gt;
 0x3100127c      A3E830000C7C      rset32	TestContinue_REX_0x31:watchData, %i0&lt;br /&gt;
 0x31001282      87EA30000C7C      rld32	[TestContinue_REX_0x31:watchData], %o1&lt;br /&gt;
 0x31001288      83E830000004      rset32	0x30000004, %o0&lt;br /&gt;
 0x3100128e      E0EE887C          rst %i0, [%fp - 4]&lt;br /&gt;
 0x31001292      40000181          call TestContinue_REX_0x31:printf&lt;br /&gt;
 0x31001296      A23F              rset5	0xffffffff, %i0&lt;br /&gt;
 0x31001298      C4EE807C          rld [%fp - 4], %o1&lt;br /&gt;
 0x3100129c      E101              rst	%i0, [%o1]&lt;br /&gt;
 0x3100129e      87E830000028      rset32	0x30000028, %o1&lt;br /&gt;
 0x310012a4      C0EE8878          rst %o0, [%fp - 8]&lt;br /&gt;
 0x310012a8      8101              rmov	%o1, %o0&lt;br /&gt;
 0x310012aa      8508              rmov	%i0, %o1&lt;br /&gt;
 0x310012ac      4000017A          call TestContinue_REX_0x31:printf&lt;br /&gt;
 0x310012b0      C0EE8874          rst %o0, [%fp - 12]&lt;br /&gt;
 0x310012b4      83C0              rretrest&lt;br /&gt;
 0x310012b6      00009DE3          unimp	0x9de3&lt;br /&gt;
 0x310012b8      9DE39F98          saverex %sp, %i0, %sp&lt;br /&gt;
 0x310012bc      A220              rset5	0x0, %i0&lt;br /&gt;
 0x310012be      E0EE887C          rst %i0, [%fp - 4]&lt;br /&gt;
 0x310012c2      83E83000004E      rset32	0x3000004E, %o0&lt;br /&gt;
 0x310012c8      E0EE8878          rst %i0, [%fp - 8]&lt;br /&gt;
 0x310012cc      40000172          call TestContinue_REX_0x31:printf&lt;br /&gt;
 0x310012d0      C0EE8874          rst %o0, [%fp - 12]&lt;br /&gt;
 0x310012d4      7FFFFFE9          call TestContinue_REX_0x31:secondHello&lt;br /&gt;
 0x310012d8      E0EE8078          rld [%fp - 8], %i0&lt;br /&gt;
 0x310012dc      83C0              rretrest&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The table below shows GR716 REX commands:&lt;br /&gt;
&lt;br /&gt;
{| class=	wikitable		&lt;br /&gt;
! style=	font-weight	: bold; | Command	&lt;br /&gt;
! style=	font-weight	: bold; | Description	&lt;br /&gt;
|-			&lt;br /&gt;
| rex [en&amp;amp;#124;ill&amp;amp;#124;tr]&amp;lt;cpuID&amp;gt; || Sets the REX mode(enable&amp;amp;#124;illegal&amp;amp;#124;transparent) for active cpu or cpuID if provided&lt;br /&gt;
|-			&lt;br /&gt;
| coderex [addr]&amp;lt;length&amp;gt; &amp;lt;force&amp;gt; || Disassemble REX instructions in memory. DMON will detect if address is in REX block and disassemble as REX. Force switch will bypass detection and disassemble as REX instruction&lt;br /&gt;
|-&lt;br /&gt;
| breakrexs [addr]&amp;lt;cpuID&amp;gt; || Force to set REX Software break point. breaks command will scan if address is in REX block and set REX software break point&lt;br /&gt;
|-			&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== DMA Controller ==&lt;br /&gt;
&lt;br /&gt;
The GR716 microcontroller have 4 separate DMA controller with internal AHB/APB bridge units (GRDMAC). The GRDMAC units described in this section provides a flexible direct memory access controller. The core can perform burst transfers of data between AHB and APB peripherals at aligned or unaligned memory addresses.&lt;br /&gt;
&lt;br /&gt;
One DMA channel per DMA controller is supported. The channel can be configured flexibly by means of two descriptor chains residing in main memory: a Memory to Buffer (M2B) chain and a Buffer to Memory (B2M) chain. Each chain is composed of a linked list of descriptors, where each descriptor specifies an AHB address and the size of the data to read/write, supporting a scatter/gather behavior.&lt;br /&gt;
&lt;br /&gt;
DMON provides a number of specific tabs to allow the user to configure the GRDMAC registers, test DMA transfers, and load/save such test configurations. It is assumed that the user is familiar with the GRDMAC hardware.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:DMON-GR716-GRDMAC-Status.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
GRDMAC status window&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:DMA-STATUS-PANEL.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
GRDMAC configuration window&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:DMA-STATUS-PANEL.gif | 800px]]&lt;br /&gt;
&lt;br /&gt;
GRDMAC descriptor configuration&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Descr-Control.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
GRDMAC waiting for trigger condition&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:STATUS-WAITING.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
GRDMAC and Descriptors status after trigger&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:STATUS-COMPLETED.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
Available commands for GRDMAC:&lt;br /&gt;
&lt;br /&gt;
{| class=	wikitable		&lt;br /&gt;
! style=	font-weight	: bold; | Command	&lt;br /&gt;
! style=	font-weight	: bold; | Description	&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] b2m add [data&amp;amp;#124;cond&amp;amp;#124;econd] ch[N][addr] || Create B2M data&amp;amp;#124;conditional&amp;amp;#124;extended conditional descriptors at address for Channel&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] b2m remove [data&amp;amp;#124;cond&amp;amp;#124;econd] ch[N] [addr] || Remove B2M descriptor at address for Channel&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] core [en&amp;amp;#124;dis] || Enable(Run) or Disable(Stop) GRDMAC Core&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] core reset || Reset GRDMAC Core to default values&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] ctrl ie [en&amp;amp;#124;dis] || Global Interrupt Enable or Disable&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] ctrl iee [en&amp;amp;#124;dis] || Interrupt Enable or Disable for Errors&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] ctrl me [en&amp;amp;#124;dis] || Extended Mode Enable or Disable&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] ctrl ns [en&amp;amp;#124;dis] || No Starve Mode Enable or Disable&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] ctrl sm [en&amp;amp;#124;dis] || Simplified mode Enable or Disable&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] ctrl te [en&amp;amp;#124;dis] || Timer Enable or Disable&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] ech [en&amp;amp;#124;dis][all&amp;amp;#124;ch# ch#+1] || Set Channel/Channels/All Channels Enabled/Disabled&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] ech [en&amp;amp;#124;dis][ch#-ch#+n] || Set Channel Enabled or Disabled for Range of Channels&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] eirq [en&amp;amp;#124;dis] || Set Interrupt enable for Errors (IEE)&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] error reset || Reset Error Register&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] irq [en&amp;amp;#124;dis] || Set GRDMAC Global Interrupt Enable or Disable (IE)&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] irq [en&amp;amp;#124;dis][all&amp;amp;#124;ch# ch#+1] || Set Interrupt Mask for Channel/Channels/All Channels and Enable Global IRQ&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] irq [en&amp;amp;#124;dis][ch#-ch#+n] || Set Interrupt Mask for Range of Channels and Enable Global IRQ&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] irq reset || Reset Interrupt Flag Register for all channels&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] load [file] || Load GRDMAC configurations from XML file&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] m2b add [data&amp;amp;#124;cond&amp;amp;#124;econd] ch[N] [addr] || Create M2B data&amp;amp;#124;conditional&amp;amp;#124;extended conditional descriptors at address for Channel&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] m2b remove [data&amp;amp;#124;cond&amp;amp;#124;econd] ch[N] [addr] || Remove M2B descriptor at address for Channel&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] save [file] || Save GRDMAC configuration to XML file&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] sbufdata || Display Internal Buffer Readout Area&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] scan || Scan M2B and B2M descriptor linked lists using Channel Vector Pointer&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] sdata [addr] || Print DMA data after successful B2M Descriptor at address&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] set cvp [value] || Set Channel Vector Pointer (CVP)&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] set trv [value] || Set Timer Reset Value (TIMER_RST)&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] status [offset] || Display GRDMAC core status of All registers or at offset (i.e.0x04) to the screen&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] tsl [0&amp;amp;#124;32&amp;amp;#124;64&amp;amp;#124;128] || Set Transfer Size limit (TSL)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
DEMO&lt;br /&gt;
&lt;br /&gt;
Basic GRDMAC Custom Configurations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;youtube&amp;gt;https://youtu.be/82-DiU-clj0&amp;lt;/youtube&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://jira.ocetechnology.com:22091/Grdmacbasic.mp4 Use this link if problems with youtube above]&lt;br /&gt;
&lt;br /&gt;
Debugging GRDMAC using DMON&lt;br /&gt;
&lt;br /&gt;
&amp;lt;youtube&amp;gt;https://youtu.be/7AQhZcodmtg&amp;lt;/youtube&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://jira.ocetechnology.com:22091/Grdmacdebug.mp4 Use this link if problems with youtube above]&lt;br /&gt;
&lt;br /&gt;
Sample script:&lt;br /&gt;
&lt;br /&gt;
 memset&lt;br /&gt;
 write DLRAM_0_START 0x0              // Set Flag to 0&lt;br /&gt;
 write 0x40000300 0x0 0x400           // Clear memory&lt;br /&gt;
 write 0x30000004 0xcafebabe 0x400    // Set Data to be transferred&lt;br /&gt;
 grdmac_0 core reset                  // Reset Core&lt;br /&gt;
 grdmac_0 load config.xml             // Load GRDMAC and Descriptors configurations. Copy content of this [[Media:CopyMeAndCreateXml.pdf|file]] and save as config.xml &lt;br /&gt;
 grdmac_0 core  en                    // Start the core&lt;br /&gt;
 write DLRAM_0_START 0x1              // Set Flag to 1 to trigger data descriptor&lt;br /&gt;
 grdmac_0 sdata 0x40000120            // Output transferred data&lt;br /&gt;
&lt;br /&gt;
== IO Switch Matrix ==&lt;br /&gt;
&lt;br /&gt;
The I/O switch matrix provides access to several I/O units. When an interface is not activated, its pins automatically become general purpose I/O. After reset, all I/O switch matrix pins are defined as inputs until programmed otherwise.&lt;br /&gt;
 &lt;br /&gt;
Configuration and assigning of functions to external I/O is flexible and is controlled by software via a set of registers.&lt;br /&gt;
&lt;br /&gt;
DMON loads in configuration file '''iomx.config''' which located in DMON installation directory '''C:\Program Files (x86)\DMON\Local'''&lt;br /&gt;
&lt;br /&gt;
User can modify all those configurations or create new custom that will be loaded when DMON starts. &lt;br /&gt;
&lt;br /&gt;
Then, configuration can be applied using &amp;quot;''iomx set name''&amp;quot; command when DMON started or  &amp;quot;''-iomx set name''&amp;quot; switch command at DMON initialization.&lt;br /&gt;
&lt;br /&gt;
User can autocomplete configuration names using tab after &amp;quot;''iomx set''&amp;quot; or display all configurations starting with some combination of letters.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=	wikitable		&lt;br /&gt;
! style=	font-weight	: bold; | Command	&lt;br /&gt;
! style=	font-weight	: bold; | Description	&lt;br /&gt;
|-			&lt;br /&gt;
| iomx set [configName configName ...] || Set IOMX configurations for Device or Array of Devices&lt;br /&gt;
|-			&lt;br /&gt;
| -iomx set [configName configName ...] || Switch to set IOMX configurations for Device or Array of Devices, when DMON starts &lt;br /&gt;
|-&lt;br /&gt;
| iomx setpin [gpioN][val] || Set IOMX GPIO pin to value&lt;br /&gt;
|-&lt;br /&gt;
| iomx show &amp;lt;all&amp;amp;#124;configName&amp;gt; || Display all available IOMX configurations or Search by prefix&lt;br /&gt;
|-&lt;br /&gt;
| iomx validate || Validate IOMX configurations&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
iomx validate sample output: &lt;br /&gt;
 DMON &amp;gt; iomx validate&lt;br /&gt;
 GPIO[00]  mem_addr_0&lt;br /&gt;
 GPIO[01]  mem_addr_1&lt;br /&gt;
 GPIO[02]  mem_addr_2&lt;br /&gt;
 GPIO[03]  mem_addr_3&lt;br /&gt;
 GPIO[04]  mem_addr_4&lt;br /&gt;
 GPIO[05]  mem_addr_5&lt;br /&gt;
 GPIO[06]  mem_addr_6&lt;br /&gt;
 GPIO[07]  mem_addr_7&lt;br /&gt;
 GPIO[08]  mem_addr_8&lt;br /&gt;
 GPIO[09]  mem_addr_9&lt;br /&gt;
 GPIO[10]  mem_addr_10&lt;br /&gt;
 GPIO[11]  mem_addr_11&lt;br /&gt;
 GPIO[12]  mem_addr_12&lt;br /&gt;
 GPIO[13]  mem_addr_13&lt;br /&gt;
 GPIO[14]  mem_addr_14&lt;br /&gt;
 GPIO[15]  mem_addr_15&lt;br /&gt;
 GPIO[16]  mem_addr_16&lt;br /&gt;
 GPIO[17]  mem_addr_17&lt;br /&gt;
 GPIO[18]  mem_addr_18&lt;br /&gt;
 GPIO[19]  ram_csn_0&lt;br /&gt;
 GPIO[20]  gpio 20&lt;br /&gt;
 GPIO[21]  gpio 21&lt;br /&gt;
 GPIO[22]  gpio 22&lt;br /&gt;
 GPIO[23]  gpio 23&lt;br /&gt;
 GPIO[24]  gpio 24&lt;br /&gt;
 GPIO[25]  mem_data_0&lt;br /&gt;
 GPIO[26]  mem_data_1&lt;br /&gt;
 GPIO[27]  mem_data_2&lt;br /&gt;
 GPIO[28]  mem_data_3&lt;br /&gt;
 GPIO[29]  mem_data_4&lt;br /&gt;
 GPIO[30]  mem_data_5&lt;br /&gt;
 GPIO[31]  mem_data_6&lt;br /&gt;
 GPIO[32]  mem_data_7&lt;br /&gt;
 GPIO[33]  mem_oen&lt;br /&gt;
 GPIO[34]  mem_wrn&lt;br /&gt;
 GPIO[35]  gpio 35&lt;br /&gt;
 GPIO[36]  gpio 36&lt;br /&gt;
 GPIO[37]  gpio 37&lt;br /&gt;
 GPIO[38]  gpio 38&lt;br /&gt;
 GPIO[39]  gpio 39&lt;br /&gt;
 GPIO[40]  gpio 40&lt;br /&gt;
 GPIO[41]  gpio 41&lt;br /&gt;
 GPIO[42]  gpio 42&lt;br /&gt;
 GPIO[43]  gpio 43&lt;br /&gt;
 GPIO[44]  gpio 44&lt;br /&gt;
 GPIO[45]  gpio 45&lt;br /&gt;
 GPIO[46]  gpio 46&lt;br /&gt;
 GPIO[47]  gpio 47&lt;br /&gt;
 GPIO[48]  gpio 48&lt;br /&gt;
 GPIO[49]  mem_addr_19&lt;br /&gt;
 GPIO[50]  mem_addr_20&lt;br /&gt;
 GPIO[51]  gpio 51 &lt;br /&gt;
 GPIO[52]  gpio 52 &lt;br /&gt;
 GPIO[53]  gpio 53 &lt;br /&gt;
 GPIO[54]  gpio 54 &lt;br /&gt;
 GPIO[55]  gpio 55&lt;br /&gt;
 GPIO[56]  gpio 56&lt;br /&gt;
 GPIO[57]  gpio 57&lt;br /&gt;
 GPIO[58]  gpio 58&lt;br /&gt;
 GPIO[59]  gpio 59&lt;br /&gt;
 GPIO[60]  gpio 60&lt;br /&gt;
 GPIO[61]  gpio 61&lt;br /&gt;
 GPIO[62]  gpio 62&lt;br /&gt;
 GPIO[63]  gpio 63&lt;br /&gt;
&lt;br /&gt;
iomx validate sample output with duplicated pin configurations:&lt;br /&gt;
 DMON &amp;gt; iomx validate&lt;br /&gt;
 GPIO[00]  mem_addr_0&lt;br /&gt;
 GPIO[01]  mem_addr_1&lt;br /&gt;
 GPIO[02]  mem_addr_2&lt;br /&gt;
 GPIO[03]  mem_addr_3&lt;br /&gt;
 GPIO[04]  mem_addr_4&lt;br /&gt;
 GPIO[05]  mem_addr_5&lt;br /&gt;
 GPIO[06]  mem_addr_6&lt;br /&gt;
 GPIO[07]  mem_addr_7&lt;br /&gt;
 GPIO[08]  mem_addr_8&lt;br /&gt;
 GPIO[09]  mem_addr_9&lt;br /&gt;
 GPIO[10]  mem_addr_10&lt;br /&gt;
 GPIO[11]  mem_addr_11&lt;br /&gt;
 GPIO[12]  mem_addr_12&lt;br /&gt;
 GPIO[13]  can_tx_0&lt;br /&gt;
 GPIO[14]  can_rx_0&lt;br /&gt;
 GPIO[15]  can_en_0&lt;br /&gt;
 GPIO[16]  mem_addr_16&lt;br /&gt;
 GPIO[17]  mem_addr_17&lt;br /&gt;
 GPIO[18]  mem_addr_18&lt;br /&gt;
 GPIO[19]  ram_csn_0&lt;br /&gt;
 GPIO[20]  gpio 20&lt;br /&gt;
 GPIO[21]  gpio 21&lt;br /&gt;
 GPIO[22]  gpio 22&lt;br /&gt;
 GPIO[23]  gpio 23&lt;br /&gt;
 GPIO[24]  gpio 24&lt;br /&gt;
 GPIO[25]  mem_data_0&lt;br /&gt;
 GPIO[26]  mem_data_1&lt;br /&gt;
 GPIO[27]  mem_data_2&lt;br /&gt;
 GPIO[28]  mem_data_3&lt;br /&gt;
 GPIO[29]  mem_data_4&lt;br /&gt;
 GPIO[30]  mem_data_5&lt;br /&gt;
 GPIO[31]  mem_data_6&lt;br /&gt;
 GPIO[32]  mem_data_7&lt;br /&gt;
 GPIO[33]  mem_oen&lt;br /&gt;
 GPIO[34]  mem_wrn&lt;br /&gt;
 GPIO[35]  gpio 35&lt;br /&gt;
 GPIO[36]  gpio 36&lt;br /&gt;
 GPIO[37]  can_tx_0 Already mapped&lt;br /&gt;
 GPIO[38]  can_rx_0 Already mapped&lt;br /&gt;
 GPIO[39]  can_en_0 Already mapped&lt;br /&gt;
 GPIO[40]  gpio 40&lt;br /&gt;
 GPIO[41]  gpio 41&lt;br /&gt;
 GPIO[42]  gpio 42&lt;br /&gt;
 GPIO[43]  gpio 43&lt;br /&gt;
 GPIO[44]  gpio 44&lt;br /&gt;
 GPIO[45]  gpio 45&lt;br /&gt;
 GPIO[46]  gpio 46&lt;br /&gt;
 GPIO[47]  gpio 47&lt;br /&gt;
 GPIO[48]  gpio 48&lt;br /&gt;
 GPIO[49]  mem_addr_19&lt;br /&gt;
 GPIO[50]  mem_addr_20&lt;br /&gt;
 GPIO[51]  gpio 51&lt;br /&gt;
 GPIO[52]  gpio 52&lt;br /&gt;
 GPIO[53]  gpio 53&lt;br /&gt;
 GPIO[54]  gpio 54&lt;br /&gt;
 GPIO[55]  gpio 55&lt;br /&gt;
 GPIO[56]  gpio 56&lt;br /&gt;
 GPIO[57]  gpio 57&lt;br /&gt;
 GPIO[58]  gpio 58&lt;br /&gt;
 GPIO[59]  gpio 59&lt;br /&gt;
 GPIO[60]  gpio 60&lt;br /&gt;
 GPIO[61]  gpio 61&lt;br /&gt;
 GPIO[62]  gpio 62&lt;br /&gt;
 GPIO[63]  gpio 63&lt;br /&gt;
&lt;br /&gt;
== Memory Protection ==&lt;br /&gt;
&lt;br /&gt;
The GR716 microcontroller has 2 separate AMBA memory protection units (MEMPROT). The MEMPROT units have the capability to detect and protect memory areas from write accesses. The first memory protection unit (MEMPROT0) is connected to Main AHB bus and the second memory protection unit (MEMPROT1) is connected to the DMA AMBA bus. Each memory protection unit has a unique address for configuration and status.&lt;br /&gt;
The control and status registers for the memory protection units are located on APB bus in the address range 0x80005000 to 0x80005FFF  0x8010A000 to 0x8010AFFF.&lt;br /&gt;
&lt;br /&gt;
DMON provides the commands below to configure memory protection.&lt;br /&gt;
&lt;br /&gt;
{| class=	wikitable		&lt;br /&gt;
! style=	font-weight	: bold; | Command	&lt;br /&gt;
! style=	font-weight	: bold; | Description	&lt;br /&gt;
|-			&lt;br /&gt;
| mprot reg || Show GRMEMPRO registers&lt;br /&gt;
|-&lt;br /&gt;
| mprot set [n][saddr][eaddr][none&amp;amp;#124;all&amp;amp;#124;g0-g15..] || Protect area [seg num][s address][e address][none&amp;amp;#124;all or array of g0-g15]&lt;br /&gt;
|-			&lt;br /&gt;
|}&lt;br /&gt;
Memory Protection Device View&lt;br /&gt;
&lt;br /&gt;
[[File:MemProtUnit.png |Memory Protection Device View]]&lt;br /&gt;
&lt;br /&gt;
Memory Protection Device View (enabled)&lt;br /&gt;
&lt;br /&gt;
[[File:MemProtEnabled.png|Memory Protection Device Enabled]]&lt;br /&gt;
&lt;br /&gt;
== Clock Gating options ==&lt;br /&gt;
&lt;br /&gt;
The GR716 microcontroller have 2 separate clock gating units. Each clock gating unit will control its own clock domains and have a unique AMBA address.&lt;br /&gt;
&lt;br /&gt;
The clock gating units provide a means to save power by disabling the clock to unused functional blocks. These cores provide a mechanism to automatically disable the clock to LEON processors in power-down mode, and optionally also to disable the clock for shared floating-point units. The cores also provide a mechanism to reset, enable clock and disable clocks for most functional blocks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=	wikitable		&lt;br /&gt;
! style=	font-weight	: bold; | Command	&lt;br /&gt;
! style=	font-weight	: bold; | Description	&lt;br /&gt;
|-			&lt;br /&gt;
| grcg [enable&amp;amp;#124;disable][all&amp;amp;#124;bit..bitN] || Enable&amp;amp;#124;Disable all, single bit or array of bits for GRCLKGATE_0&lt;br /&gt;
|-			&lt;br /&gt;
| -grcg [enable&amp;amp;#124;disable][all&amp;amp;#124;bit..bitN] || Switch to Enable&amp;amp;#124;Disable all, single bit or array of bits for GRCLKGATE_0 or -grcg_1 for GRCLKGATE_1, at DMON start up&lt;br /&gt;
|-&lt;br /&gt;
| grcg reg || Show register values for GRCLKGATE_0&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:DMON-GR716-CLKGATE-top.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:DMON-GR716-CLKGATE-console.png |800px]]&lt;br /&gt;
&lt;br /&gt;
[[File:DMON-GR716-CLKGATE-REG-enable.png|800px]]&lt;br /&gt;
&lt;br /&gt;
[[File:DMON-GR716-CLKGATE-REG-unlock.png|800px]]&lt;br /&gt;
&lt;br /&gt;
[[File:DMON-GR716-CLKGATE-REG-reset.png|800px]]&lt;br /&gt;
&lt;br /&gt;
[[File:DMON-GR716-CLKGATE-REG-FPU.png|800px]]&lt;br /&gt;
&lt;br /&gt;
== Commands ==&lt;br /&gt;
&lt;br /&gt;
The table below is a summary of commands specific to the GR716.&lt;br /&gt;
&lt;br /&gt;
{| class=	wikitable		&lt;br /&gt;
! style=	font-weight	: bold; | Command	&lt;br /&gt;
! style=	font-weight	: bold; | Description	&lt;br /&gt;
|-&lt;br /&gt;
| breakrexs [addr]&amp;lt;cpuID&amp;gt; || Force to set REX Software break point. breaks command will scan if address is in REX block and set REX software break point&lt;br /&gt;
|- &lt;br /&gt;
| coderex [addr]&amp;lt;length&amp;gt; &amp;lt;force&amp;gt; || Disassemble REX instructions in memory. DMON will detect if address is in REX block and disassemble as REX. Force switch will bypass detection and disassemble as REX instruction&lt;br /&gt;
|-&lt;br /&gt;
| dlram edac [enable&amp;amp;#124;disable]   ||        Enable&amp;amp;#124;Disable EDAC&lt;br /&gt;
|-&lt;br /&gt;
| dlram scrub [enable&amp;amp;#124;disable]  ||        Enable&amp;amp;#124;Disable Scruber &lt;br /&gt;
|-&lt;br /&gt;
| examine16 [addr]&amp;lt;half-word n&amp;gt;      ||        Display half-word from address&lt;br /&gt;
|- &lt;br /&gt;
| gpio pulse status  ||  Show Pulse register for GRGPIO&lt;br /&gt;
|- &lt;br /&gt;
| gradcdac config  || Display status information for the GRADCDAC core&lt;br /&gt;
|- &lt;br /&gt;
| grcan [enable&amp;amp;#124;disable]  || Enable&amp;amp;#124;Disable the GRCAN receiver&lt;br /&gt;
|- &lt;br /&gt;
| grcan reset  || Resets the GRCAN receiver&lt;br /&gt;
|- &lt;br /&gt;
| grcan status  || Show register values for GRCAN&lt;br /&gt;
|-&lt;br /&gt;
| grcan_1 [enable&amp;amp;#124;disable]  || Enable&amp;amp;#124;Disable the GRCAN receiver&lt;br /&gt;
|- &lt;br /&gt;
| grcan_1 reset  || Resets the GRCAN receiver&lt;br /&gt;
|- &lt;br /&gt;
| grcan_1 status  || Show register values for GRCAN&lt;br /&gt;
|- &lt;br /&gt;
| grcg [enable&amp;amp;#124;disable][all&amp;amp;#124;bit..bitN] || Enable&amp;amp;#124;Disable all, single bit or array of bits for GRCLKGATE_0&lt;br /&gt;
|- &lt;br /&gt;
| grcg reg || Show register values for GRCLKGATE_0&lt;br /&gt;
|-&lt;br /&gt;
| grcg_1 [enable&amp;amp;#124;disable][all&amp;amp;#124;bit..bitN] || Enable&amp;amp;#124;Disable all, single bit or array of bits for GRCLKGATE_1&lt;br /&gt;
|- &lt;br /&gt;
| grcg_1 reg || Show register values for GRCLKGATE_1&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] b2m add [data&amp;amp;#124;cond&amp;amp;#124;econd] ch[N][addr] || Create B2M data&amp;amp;#124;conditional&amp;amp;#124;extended conditional descriptors at address for Channel&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] b2m remove [data&amp;amp;#124;cond&amp;amp;#124;econd] ch[N] [addr] || Remove B2M descriptor at address for Channel&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] core [en&amp;amp;#124;dis] || Enable(Run) or Disable(Stop) GRDMAC Core&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] core reset || Reset GRDMAC Core to default values&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] ctrl ie [en&amp;amp;#124;dis] || Global Interrupt Enable or Disable&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] ctrl iee [en&amp;amp;#124;dis] || Interrupt Enable or Disable for Errors&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] ctrl me [en&amp;amp;#124;dis] || Extended Mode Enable or Disable&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] ctrl ns [en&amp;amp;#124;dis] || No Starve Mode Enable or Disable&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] ctrl sm [en&amp;amp;#124;dis] || Simplified mode Enable or Disable&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] ctrl te [en&amp;amp;#124;dis] || Timer Enable or Disable&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] ech [en&amp;amp;#124;dis][all&amp;amp;#124;ch# ch#+1] || Set Channel/Channels/All Channels Enabled/Disabled&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] ech [en&amp;amp;#124;dis][ch#-ch#+n] || Set Channel Enabled or Disabled for Range of Channels&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] eirq [en&amp;amp;#124;dis] || Set Interrupt enable for Errors (IEE)&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] error reset || Reset Error Register&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] irq [en&amp;amp;#124;dis] || Set GRDMAC Global Interrupt Enable or Disable (IE)&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] irq [en&amp;amp;#124;dis][all&amp;amp;#124;ch# ch#+1] || Set Interrupt Mask for Channel/Channels/All Channels and Enable Global IRQ&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] irq [en&amp;amp;#124;dis][ch#-ch#+n] || Set Interrupt Mask for Range of Channels and Enable Global IRQ&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] irq reset || Reset Interrupt Flag Register for all channels&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] load [file] || Load GRDMAC configurations from XML file&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] m2b add [data&amp;amp;#124;cond&amp;amp;#124;econd] ch[N] [addr] || Create M2B data&amp;amp;#124;conditional&amp;amp;#124;extended conditional descriptors at address for Channel&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] m2b remove [data&amp;amp;#124;cond&amp;amp;#124;econd] ch[N] [addr] || Remove M2B descriptor at address for Channel&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] save [file] || Save GRDMAC configuration to XML file&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] sbufdata || Display Internal Buffer Readout Area&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] scan || Scan M2B and B2M descriptor linked lists using Channel Vector Pointer&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] sdata [addr] || Print DMA data after successful B2M Descriptor at address&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] set cvp [value] || Set Channel Vector Pointer (CVP)&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] set trv [value] || Set Timer Reset Value (TIMER_RST)&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] status [offset] || Display GRDMAC core status of All registers or at offset (i.e.0x04) to the screen&lt;br /&gt;
|- &lt;br /&gt;
| grdmac_[devID] tsl [0&amp;amp;#124;32&amp;amp;#124;64&amp;amp;#124;128] || Set Transfer Size limit (TSL)&lt;br /&gt;
|- &lt;br /&gt;
| grpwm &amp;lt;dev#&amp;gt; enable&amp;amp;#124;disable  || Enable or Disable the GRPWM core&lt;br /&gt;
|- &lt;br /&gt;
| grpwm &amp;lt;dev#&amp;gt; status  || Display status information for the GRPWM core&lt;br /&gt;
|- &lt;br /&gt;
| grpwrx [enable&amp;amp;#124;disable]  || Enable&amp;amp;#124;Disable the GRPWRX reciever&lt;br /&gt;
|- &lt;br /&gt;
| grpwrx dma [enable&amp;amp;#124;disable]  || GRPWRX dma Enable&amp;amp;#124;Disable&lt;br /&gt;
|- &lt;br /&gt;
| grpwrx reset  || Resets the GRPWRX reciever&lt;br /&gt;
|- &lt;br /&gt;
| grpwrx status  || Show register values for GRPWRX&lt;br /&gt;
|- &lt;br /&gt;
| grpwtx [enable&amp;amp;#124;disable]  || Enable&amp;amp;#124;Disable the GRPWTX reciever&lt;br /&gt;
|- &lt;br /&gt;
| grpwtx dma [enable&amp;amp;#124;disable]  ||  GRPWTX DMA Enable&amp;amp;#124;Disable &lt;br /&gt;
|- &lt;br /&gt;
| grpwtx reset  ||  Resets the GRPWTX Transmitter&lt;br /&gt;
|- &lt;br /&gt;
| grpwtx status  || Show register values for GRPWTX&lt;br /&gt;
|- &lt;br /&gt;
| i2c2ahb enable&amp;amp;#124;disable  ||  Enable or Disable the I2C2AHB core&lt;br /&gt;
|- &lt;br /&gt;
| i2c2ahb irq enable&amp;amp;#124;disable  || Display status information for the I2C2AHB core&lt;br /&gt;
|- &lt;br /&gt;
| i2c2ahb status  || Display status information for the I2C2AHB core&lt;br /&gt;
|- &lt;br /&gt;
| ilram edac [enable&amp;amp;#124;disable]      ||     Enable&amp;amp;#124;Disable EDAC&lt;br /&gt;
|-&lt;br /&gt;
| ilram scrub [enable&amp;amp;#124;disable]     ||     Enable&amp;amp;#124;Disable Scruber&lt;br /&gt;
|-&lt;br /&gt;
| iomx set [configName configName ...] || Set IOMX configurations for Device or Array of Devices&lt;br /&gt;
|- &lt;br /&gt;
| iomx setpin [gpioN][val] || Set IOMX GPIO pin to value&lt;br /&gt;
|- &lt;br /&gt;
| iomx show &amp;lt;all&amp;amp;#124;configName&amp;gt; || Display all available IOMX configurations or Search by prefix&lt;br /&gt;
|- &lt;br /&gt;
| iomx validate || Validate IOMX configurations&lt;br /&gt;
|- &lt;br /&gt;
| l3stat clear [cnt] || Clear the counter cnt&lt;br /&gt;
|- &lt;br /&gt;
| l3stat display [workers/counters] &amp;lt;all&amp;amp;#124;n&amp;gt; || Display information on workers or counters&lt;br /&gt;
|-&lt;br /&gt;
| l3stat duration [cnt][enable&amp;amp;#124;disable]&amp;lt;lvl&amp;gt; || If Enabled the core will save the maximum time the selected event has been at the level specified by the EL field if level(lvl) is present the counter will count the cycles, otherwise will count the time between event assertions&lt;br /&gt;
|-&lt;br /&gt;
| l3stat events || Show all events that can be selected/counted&lt;br /&gt;
|-&lt;br /&gt;
| l3stat events [hex][abbr][descr] || Add new event to DMON (hardware must support this code). hex-&amp;gt;code value, abbr-&amp;gt;abbreviation, descr-&amp;gt;description&lt;br /&gt;
|- &lt;br /&gt;
| l3stat poll [cnt][int]&amp;lt;hold&amp;gt;&amp;lt;save&amp;gt; || Continuously poll counter(cnt) at interval(int)(min value 100 ms). If hold parameter is passed DMON will poll for Counter control register till software enables the counter and only then will start to poll for counter value. If save parameter is used, DMON will save data to csv file&lt;br /&gt;
|-&lt;br /&gt;
| l3stat runpoll [cnt][int]&amp;lt;save&amp;gt; || Poll counter(cnt) at interval(int)(min value 100 ms) while application is running. DMON will start polling when program starts running on the board. If breakpoint is hit, DMON will pause polling and resume after program will continue. If save parameter is used, DMON will save data to csv file&lt;br /&gt;
|- &lt;br /&gt;
| l3stat set [cnt][flag=value] || Count the event using counter cnt on processor cpu. Use enable flag(en) the last Available flags: cpu=val, event=val, cl=1&amp;amp;#124;0, su=0&amp;amp;#124;1&amp;amp;#124;2, en=1&amp;amp;#124;0 &lt;br /&gt;
|-&lt;br /&gt;
| l3stat status || Display status of all available counters&lt;br /&gt;
|-&lt;br /&gt;
| l3stat stop [cnt&amp;amp;#124;all] || Stop polling of Counter Register for counter(cnt) or all and disable counter&lt;br /&gt;
|-&lt;br /&gt;
| l3stat_1 clear [cnt] || Clear the counter cnt&lt;br /&gt;
|- &lt;br /&gt;
| l3stat_1 display [workers/counters] &amp;lt;all&amp;amp;#124;n&amp;gt; || Display information on workers or counters&lt;br /&gt;
|-&lt;br /&gt;
| l3stat_1 duration [cnt][enable&amp;amp;#124;disable]&amp;lt;lvl&amp;gt; || If Enabled the core will save the maximum time the selected event has been at the level specified by the EL field if level(lvl) is present the counter will count the cycles, otherwise will count the time between event assertions&lt;br /&gt;
|-&lt;br /&gt;
| l3stat_1 events || Show all events that can be selected/counted&lt;br /&gt;
|-&lt;br /&gt;
| l3stat_1 events [hex][abbr][descr] || Add new event to DMON (hardware must support this code). hex-&amp;gt;code value, abbr-&amp;gt;abbreviation, descr-&amp;gt;description&lt;br /&gt;
|- &lt;br /&gt;
| l3stat_1 poll [cnt][int]&amp;lt;hold&amp;gt;&amp;lt;save&amp;gt; || Continuously poll counter(cnt) at interval(int)(min value 100 ms). If hold parameter is passed DMON will poll for Counter control register till software enables the counter and only then will start to poll for counter value. If save parameter is used, DMON will save data to csv file&lt;br /&gt;
|-&lt;br /&gt;
| l3stat_1 runpoll [cnt][int]&amp;lt;save&amp;gt; || Poll counter(cnt) at interval(int)(min value 100 ms) while application is running. DMON will start polling when program starts running on the board. If breakpoint is hit, DMON will pause polling and resume after program will continue. If save parameter is used, DMON will save data to csv file&lt;br /&gt;
|- &lt;br /&gt;
| l3stat_1 set [cnt][flag=value] || Count the event using counter cnt on processor cpu. Use enable flag(en) the last Available flags: cpu=val, event=val, cl=1&amp;amp;#124;0, su=0&amp;amp;#124;1&amp;amp;#124;2, en=1&amp;amp;#124;0 &lt;br /&gt;
|-&lt;br /&gt;
| l3stat_1 status || Display status of all available counters&lt;br /&gt;
|-&lt;br /&gt;
| l3stat_1 stop [cnt&amp;amp;#124;all] || Stop polling of Counter Register for counter(cnt) or all and disable counter&lt;br /&gt;
|-&lt;br /&gt;
| mprot reg || Show GRMEMPRO registers&lt;br /&gt;
|- &lt;br /&gt;
| mprot set [n][saddr][eaddr][none&amp;amp;#124;all&amp;amp;#124;g0-g15..] || Protect area [seg num][s address][e address][none&amp;amp;#124;all or array of g0-g15]&lt;br /&gt;
|- &lt;br /&gt;
| mprot_1 reg || Show GRMEMPRO registers&lt;br /&gt;
|- &lt;br /&gt;
| mprot_1 set [n][saddr][eaddr][none&amp;amp;#124;all&amp;amp;#124;g0-g15..] || Protect area [seg num][s address][e address][none&amp;amp;#124;all or array of g0-g15]&lt;br /&gt;
|-&lt;br /&gt;
| rex [en&amp;amp;#124;ill&amp;amp;#124;tr]&amp;lt;cpuID&amp;gt; || Sets the REX mode(enable&amp;amp;#124;illegal&amp;amp;#124;transparent) for active cpu or cpuID if provided&lt;br /&gt;
|- &lt;br /&gt;
| spi2ahb enable&amp;amp;#124;disable  || Enable or Disable the SPI2AHB core&lt;br /&gt;
|- &lt;br /&gt;
| spi2ahb irq enable&amp;amp;#124;disable  || Enable or disable interrupts for SPI2AHB core&lt;br /&gt;
|-&lt;br /&gt;
| spi2ahb status  || Display status information for the SPI2AHB core&lt;br /&gt;
|-  &lt;br /&gt;
| spislave status   || Show registers values for SPI4SPACE&lt;br /&gt;
|-&lt;br /&gt;
| spislave reset   || Reset SPI4SPACE device&lt;br /&gt;
|-&lt;br /&gt;
| spim edac &amp;lt;enabled&amp;amp;#124;disable&amp;gt; || Enable or Disable EDAC in SPIMCTRL&lt;br /&gt;
|- &lt;br /&gt;
| spwtdp status  || Display status information for the SPWTDP core&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= PROM Builder =&lt;br /&gt;
&lt;br /&gt;
== DMON PROM Builder Introduction ==&lt;br /&gt;
&lt;br /&gt;
DMON Prom Builder can be used to configure basic prom settings, create prom file and use DMON commands to load to the target flash.&lt;br /&gt;
This feature is available in DMON 2.1.0.0 version. &lt;br /&gt;
&lt;br /&gt;
Prom Builder Features:&lt;br /&gt;
&lt;br /&gt;
* Save configurations to the property file&lt;br /&gt;
* Load saved configurations&lt;br /&gt;
* DMON is displaying current target memory settings for mkprom2 memory switches&lt;br /&gt;
* Easy to set basic prom configurations&lt;br /&gt;
* Prom Builder is creating make file, which can be examined and used on its own through DMON &amp;quot;buildprom&amp;quot; command or called directly from CLI with make utility&lt;br /&gt;
* Prom Builder is calling DMON flash commands after prom file was created to erase flash, check if blank, load prom file to target flash and start program on the board &lt;br /&gt;
&lt;br /&gt;
DMON provides two prom configuration files for '''E698PM'''. They located in DMON install directory at  '''DMON\Files\PROM_PM_CONFIG''' initially and copied to DMON user folder '''C:\Users\UserName\DMON\PromConfig''' when Prom Builder is started for the first time. 698PM_RAM_PROM.properties file has configurations that can be used to produce prom file to use RAM only as it does not initialize DDR2 RAM. 698PM_DDR_PROM.properties file has configurations to produce prom file to use DDR2 RAM on E698PM. Sample bdinit.c file is located in '''DMON\Files\PROM_PM_CONFIG''' directory. This file has to be compiled and put in the same directory where make file will be stored. bdinit.c can be copied from [[bdinit_PM_sample|bdinit.c]] too. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
mkprom2 must be in system path. If DMON cannot find mkprom2, PC restart required. Java does not see changes in system PATH till PC is restarted.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
Please follow the tutorials below. The sample program for E698PM used in tutorials can be found [[E698PM_LED_test.c|here]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
DMON Prom Builder can be called from DMON menu =&amp;gt; Tasks =&amp;gt; Prom Builder.&lt;br /&gt;
&lt;br /&gt;
'''DMON Prom Builder Main View:'''&lt;br /&gt;
&lt;br /&gt;
[[File:MainView.png|600px]]&lt;br /&gt;
&lt;br /&gt;
'''DMON Prom Builder Memory View:'''&lt;br /&gt;
&lt;br /&gt;
[[File:MemoryView.png|600px]]&lt;br /&gt;
&lt;br /&gt;
'''DMON Prom Builder Advanced View:'''&lt;br /&gt;
&lt;br /&gt;
[[File:AdvancedView.png|600px]]&lt;br /&gt;
&lt;br /&gt;
==DMON Commands ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=	wikitable		&lt;br /&gt;
! style=	font-weight	: bold; | Command	&lt;br /&gt;
! style=	font-weight	: bold; | Description	&lt;br /&gt;
|-			&lt;br /&gt;
| buildprom &amp;lt;cmderase,cmdblank,cmdload,cmdrun&amp;gt; mkf || Create prom by calling mkf in make utility. Pass flash commands as parameters. '''buildprom cmderase cmdload cmdrun my_make_file''' &lt;br /&gt;
|-			&lt;br /&gt;
			&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== DMON PROM Builder Tutorials ==&lt;br /&gt;
&lt;br /&gt;
'''Creating sample prom file using RAM only''':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;youtube&amp;gt;https://youtu.be/wHOZ3ydj1ps&amp;lt;/youtube&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://jira.ocetechnology.com:22091/Promram.mp4 Use this link if problems with youtube above]&lt;br /&gt;
&lt;br /&gt;
'''Creating prom file to be used with DDR2 RAM''':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;youtube&amp;gt;https://youtu.be/x3P_G1zsAgQ&amp;lt;/youtube&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://jira.ocetechnology.com:22091/Promddr2.mp4 Use this link if problems with youtube above]&lt;br /&gt;
&lt;br /&gt;
'''Building PROM file using make''':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;youtube&amp;gt;https://youtu.be/2v9hpA9kkxY&amp;lt;/youtube&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://jira.ocetechnology.com:22091/Prommake.mp4 Use this link if problems with youtube above]&lt;br /&gt;
&lt;br /&gt;
'''Creating prom file calling directly mkprom2 from CLI''':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;youtube&amp;gt;https://youtu.be/kUnkPmObefE&amp;lt;/youtube&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://jira.ocetechnology.com:22091/Promcli.mp4 Use this link if problems with youtube above]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1492</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1492"/>
		<updated>2022-04-20T13:48:27Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* oceos_init_interrrupt_manager() is failing with data store error */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 '''Documentation'''/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 '''Examples'''/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 '''include'''/                             // OCEOS header files&lt;br /&gt;
 '''OCEOS_GCC_LIB'''/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Normal operations&amp;lt;/span&amp;gt;====&lt;br /&gt;
The scheduling is started after calling [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The main structure of application flow is described below:&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] - Initialize fixed data and start system time and log&lt;br /&gt;
# Create:&lt;br /&gt;
#* [[OCEOS/oceos kernel/task#oceos_task_create()|oceos_task_create()]] - Create task, setting priority, no of jobs, ..etc.&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/mutex#oceos_mutex_create()|oceos_mutex_create()]] - Create mutexes if require&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/dataq#oceos_dataq_create()|oceos_dataq_create()]] - Create data queues if require&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/semaphore#oceos_sem_create()|oceos_sem_create()]] - Create semaphores if require&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init_finish()|oceos_init_finish()]] - Initialize dynamic data area&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] - Start the scheduler and pass control to first task&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
It is mandatory to create the number of tasks, mutexes, semaphores, and data queues declared in oceos_config.h otherwise oceos_init_finish() will return an error.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OCEOS configuration parameters are shown below. In provided demo projects these are ''oceos_config.h'' and ''oceos_config.c''. More information can be found by clicking on the link for parameter that is of interest.&lt;br /&gt;
&lt;br /&gt;
 // ''1: Includes OCEOS main header file''&lt;br /&gt;
 #include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''2: Number of Log entries.''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|NUMBER_OF_LOG_ENTRIES]]                   16 // ''16 to 1024, default 64''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''3: Number of tasks''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_TASKS]]                         3  // 1 to 255&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);''&lt;br /&gt;
 //    ''Defaults to number of tasks, as each task should have aa least one job;''&lt;br /&gt;
 //    ''If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_READYQ_ENTRIES]]                10&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''5: Number of Mutexes''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/mutex#Mutex_Configuration|NUMBER_OF_MUTEXES]]                       2  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''6: Number of Semaphores''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/semaphore#Semaphore_Configuration|NUMBER_OF_SEMAPHORES]]                    0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''7: Number of Data Qs''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/dataq#Data_Queue_Configuration|NUMBER_OF_DATAQS]]                        0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''8: LOG data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|LOG_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''9: FIXED data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|FIXED_DATA_ARRAY_SIZE_U32S]]              0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''10: DYNAMIC data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|DYN_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''11: Timed Actions''&lt;br /&gt;
 #define [[OCEOS/oceos_timed_actions#Timed_Actions_Configuration|NUMBER_OF_ACTION_ENTRIES]]                0  // ''User-modify field''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''12: Log entries base 2''&lt;br /&gt;
 #define [[OCEOS/oceos_profiling#Configuration|CS_LOG_DEF_ENTRIES_BASE2]]                0&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''13: OCEOS stack start Address''&lt;br /&gt;
 #define OCEOS_STACK_START_ADDRESS               0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''14: OCEOS stack end address''&lt;br /&gt;
 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
&lt;br /&gt;
''application_init()'' function shown below creates OCEOS configuration struct and sets configuration parameter that passed to [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * Not Used for ARM. Always Nested&lt;br /&gt;
     */&lt;br /&gt;
    app_config.interrupt_nesting_enabled     = TRUE;                          // Nesting Enabled&lt;br /&gt;
#endif&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * ARM SysTick is used for System Time&lt;br /&gt;
     */&lt;br /&gt;
    app_config.sys_time_timer_index          = SYS_TIME_TIMER_INDEX;          // 0 =&amp;gt; invalid index&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    // System time is used by timed actions, semaphores with timeout, dataqs with timeout, logging and profiling.&lt;br /&gt;
    // If all of above are not required then system time can be disabled. The system will not be interrupted by SysTick while CPU in sleep mode,&lt;br /&gt;
    //but it is not the case for SPARC targets,&lt;br /&gt;
    // as system time implemented by chaining two timers without interrupting.&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all ARM_BUILD=1 FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Troubleshooting&amp;lt;/span&amp;gt;====&lt;br /&gt;
=====oceos_init_interrrupt_manager() is failing with data store error=====&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Solution'''&amp;lt;br&amp;gt;&lt;br /&gt;
OCEOS is initializing interrupt trap table with OCEOS handler, replacing default handlers. If application is run from flash, than replacing interrupt trap table entries give data store error, as it cannot write to flash. &lt;br /&gt;
&lt;br /&gt;
We would suggest you to move interrupt vector table __bcc_trap_table_svt_1 to SRAM. __bcc_trap_table_svt_1 is a weak symbol, so could be recreated and replaced by linker. If you are planning to add other trap handlers, you need to modify trap tables at compile time or move all trap tables to SRAM to use bcc_set_trap() at run time. &lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 4 – Timer interrupt starts task&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- =&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
In common situation embedded application would call list of functions in a while loop and interrupt service routines are used for critical operations.&amp;lt;br&amp;gt;&lt;br /&gt;
Using RTOS for the same application would make developers life easier and would save power consumption. &lt;br /&gt;
Each function in a list of while loop can represent the task and started only when something really happen. Most of RTOS available today would use priority controlled round-robin scheduling. Where the tasks require different response time developer could assigned different priorities for those tasks and scheduling according to those priorities. Tasks with the same priorities are scheduled using round-robin.&lt;br /&gt;
&lt;br /&gt;
This is where OCEOS is different. &lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1491</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1491"/>
		<updated>2022-04-20T13:46:51Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* bcc_set_trap() failing in oceos_init_interrrupt_manager() with data store error */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 '''Documentation'''/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 '''Examples'''/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 '''include'''/                             // OCEOS header files&lt;br /&gt;
 '''OCEOS_GCC_LIB'''/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Normal operations&amp;lt;/span&amp;gt;====&lt;br /&gt;
The scheduling is started after calling [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The main structure of application flow is described below:&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] - Initialize fixed data and start system time and log&lt;br /&gt;
# Create:&lt;br /&gt;
#* [[OCEOS/oceos kernel/task#oceos_task_create()|oceos_task_create()]] - Create task, setting priority, no of jobs, ..etc.&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/mutex#oceos_mutex_create()|oceos_mutex_create()]] - Create mutexes if require&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/dataq#oceos_dataq_create()|oceos_dataq_create()]] - Create data queues if require&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/semaphore#oceos_sem_create()|oceos_sem_create()]] - Create semaphores if require&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init_finish()|oceos_init_finish()]] - Initialize dynamic data area&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] - Start the scheduler and pass control to first task&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
It is mandatory to create the number of tasks, mutexes, semaphores, and data queues declared in oceos_config.h otherwise oceos_init_finish() will return an error.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OCEOS configuration parameters are shown below. In provided demo projects these are ''oceos_config.h'' and ''oceos_config.c''. More information can be found by clicking on the link for parameter that is of interest.&lt;br /&gt;
&lt;br /&gt;
 // ''1: Includes OCEOS main header file''&lt;br /&gt;
 #include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''2: Number of Log entries.''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|NUMBER_OF_LOG_ENTRIES]]                   16 // ''16 to 1024, default 64''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''3: Number of tasks''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_TASKS]]                         3  // 1 to 255&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);''&lt;br /&gt;
 //    ''Defaults to number of tasks, as each task should have aa least one job;''&lt;br /&gt;
 //    ''If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_READYQ_ENTRIES]]                10&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''5: Number of Mutexes''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/mutex#Mutex_Configuration|NUMBER_OF_MUTEXES]]                       2  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''6: Number of Semaphores''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/semaphore#Semaphore_Configuration|NUMBER_OF_SEMAPHORES]]                    0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''7: Number of Data Qs''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/dataq#Data_Queue_Configuration|NUMBER_OF_DATAQS]]                        0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''8: LOG data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|LOG_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''9: FIXED data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|FIXED_DATA_ARRAY_SIZE_U32S]]              0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''10: DYNAMIC data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|DYN_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''11: Timed Actions''&lt;br /&gt;
 #define [[OCEOS/oceos_timed_actions#Timed_Actions_Configuration|NUMBER_OF_ACTION_ENTRIES]]                0  // ''User-modify field''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''12: Log entries base 2''&lt;br /&gt;
 #define [[OCEOS/oceos_profiling#Configuration|CS_LOG_DEF_ENTRIES_BASE2]]                0&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''13: OCEOS stack start Address''&lt;br /&gt;
 #define OCEOS_STACK_START_ADDRESS               0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''14: OCEOS stack end address''&lt;br /&gt;
 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
&lt;br /&gt;
''application_init()'' function shown below creates OCEOS configuration struct and sets configuration parameter that passed to [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * Not Used for ARM. Always Nested&lt;br /&gt;
     */&lt;br /&gt;
    app_config.interrupt_nesting_enabled     = TRUE;                          // Nesting Enabled&lt;br /&gt;
#endif&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * ARM SysTick is used for System Time&lt;br /&gt;
     */&lt;br /&gt;
    app_config.sys_time_timer_index          = SYS_TIME_TIMER_INDEX;          // 0 =&amp;gt; invalid index&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    // System time is used by timed actions, semaphores with timeout, dataqs with timeout, logging and profiling.&lt;br /&gt;
    // If all of above are not required then system time can be disabled. The system will not be interrupted by SysTick while CPU in sleep mode,&lt;br /&gt;
    //but it is not the case for SPARC targets,&lt;br /&gt;
    // as system time implemented by chaining two timers without interrupting.&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all ARM_BUILD=1 FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Troubleshooting&amp;lt;/span&amp;gt;====&lt;br /&gt;
=====oceos_init_interrrupt_manager() is failing with data store error=====&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Solution'''&amp;lt;br&amp;gt;&lt;br /&gt;
OCEOS is initializing interrupt trap table with OCEOS handler, replacing default handlers. If application is run from flash, than replacing interrupt trap table entries give data store error, as it cannot write to flash. &lt;br /&gt;
&lt;br /&gt;
We would suggest you to move interrupt vector table __bcc_trap_table_svt_1 to SRAM. __bcc_trap_table_svt_1 is a weak symbol, so could be recreated and be replaced by linker. If you are planning to add other trap handlers, you need to modify trap tables at compile time or move all trap tables to SRAM to use bcc_set_trap() at run time. &lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 4 – Timer interrupt starts task&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- =&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
In common situation embedded application would call list of functions in a while loop and interrupt service routines are used for critical operations.&amp;lt;br&amp;gt;&lt;br /&gt;
Using RTOS for the same application would make developers life easier and would save power consumption. &lt;br /&gt;
Each function in a list of while loop can represent the task and started only when something really happen. Most of RTOS available today would use priority controlled round-robin scheduling. Where the tasks require different response time developer could assigned different priorities for those tasks and scheduling according to those priorities. Tasks with the same priorities are scheduled using round-robin.&lt;br /&gt;
&lt;br /&gt;
This is where OCEOS is different. &lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1490</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1490"/>
		<updated>2022-04-20T13:45:19Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 '''Documentation'''/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 '''Examples'''/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 '''include'''/                             // OCEOS header files&lt;br /&gt;
 '''OCEOS_GCC_LIB'''/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Normal operations&amp;lt;/span&amp;gt;====&lt;br /&gt;
The scheduling is started after calling [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The main structure of application flow is described below:&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] - Initialize fixed data and start system time and log&lt;br /&gt;
# Create:&lt;br /&gt;
#* [[OCEOS/oceos kernel/task#oceos_task_create()|oceos_task_create()]] - Create task, setting priority, no of jobs, ..etc.&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/mutex#oceos_mutex_create()|oceos_mutex_create()]] - Create mutexes if require&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/dataq#oceos_dataq_create()|oceos_dataq_create()]] - Create data queues if require&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/semaphore#oceos_sem_create()|oceos_sem_create()]] - Create semaphores if require&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init_finish()|oceos_init_finish()]] - Initialize dynamic data area&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] - Start the scheduler and pass control to first task&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
It is mandatory to create the number of tasks, mutexes, semaphores, and data queues declared in oceos_config.h otherwise oceos_init_finish() will return an error.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OCEOS configuration parameters are shown below. In provided demo projects these are ''oceos_config.h'' and ''oceos_config.c''. More information can be found by clicking on the link for parameter that is of interest.&lt;br /&gt;
&lt;br /&gt;
 // ''1: Includes OCEOS main header file''&lt;br /&gt;
 #include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''2: Number of Log entries.''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|NUMBER_OF_LOG_ENTRIES]]                   16 // ''16 to 1024, default 64''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''3: Number of tasks''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_TASKS]]                         3  // 1 to 255&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);''&lt;br /&gt;
 //    ''Defaults to number of tasks, as each task should have aa least one job;''&lt;br /&gt;
 //    ''If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_READYQ_ENTRIES]]                10&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''5: Number of Mutexes''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/mutex#Mutex_Configuration|NUMBER_OF_MUTEXES]]                       2  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''6: Number of Semaphores''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/semaphore#Semaphore_Configuration|NUMBER_OF_SEMAPHORES]]                    0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''7: Number of Data Qs''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/dataq#Data_Queue_Configuration|NUMBER_OF_DATAQS]]                        0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''8: LOG data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|LOG_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''9: FIXED data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|FIXED_DATA_ARRAY_SIZE_U32S]]              0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''10: DYNAMIC data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|DYN_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''11: Timed Actions''&lt;br /&gt;
 #define [[OCEOS/oceos_timed_actions#Timed_Actions_Configuration|NUMBER_OF_ACTION_ENTRIES]]                0  // ''User-modify field''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''12: Log entries base 2''&lt;br /&gt;
 #define [[OCEOS/oceos_profiling#Configuration|CS_LOG_DEF_ENTRIES_BASE2]]                0&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''13: OCEOS stack start Address''&lt;br /&gt;
 #define OCEOS_STACK_START_ADDRESS               0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''14: OCEOS stack end address''&lt;br /&gt;
 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
&lt;br /&gt;
''application_init()'' function shown below creates OCEOS configuration struct and sets configuration parameter that passed to [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * Not Used for ARM. Always Nested&lt;br /&gt;
     */&lt;br /&gt;
    app_config.interrupt_nesting_enabled     = TRUE;                          // Nesting Enabled&lt;br /&gt;
#endif&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * ARM SysTick is used for System Time&lt;br /&gt;
     */&lt;br /&gt;
    app_config.sys_time_timer_index          = SYS_TIME_TIMER_INDEX;          // 0 =&amp;gt; invalid index&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    // System time is used by timed actions, semaphores with timeout, dataqs with timeout, logging and profiling.&lt;br /&gt;
    // If all of above are not required then system time can be disabled. The system will not be interrupted by SysTick while CPU in sleep mode,&lt;br /&gt;
    //but it is not the case for SPARC targets,&lt;br /&gt;
    // as system time implemented by chaining two timers without interrupting.&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all ARM_BUILD=1 FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Troubleshooting&amp;lt;/span&amp;gt;====&lt;br /&gt;
=====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;bcc_set_trap() failing in oceos_init_interrrupt_manager() with data store error&amp;lt;/span&amp;gt;=====&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Solution'''&amp;lt;br&amp;gt;&lt;br /&gt;
OCEOS is initializing interrupt trap table with OCEOS handler, replacing default handlers. If application is run from flash, than replacing interrupt trap table entries give data store error, as it cannot write to flash. &lt;br /&gt;
&lt;br /&gt;
We would suggest you to move interrupt vector table __bcc_trap_table_svt_1 to SRAM. __bcc_trap_table_svt_1 is a weak symbol, so could be recreated and be replaced by linker. If you are planning to add other trap handlers, you need to modify trap tables at compile time or move all trap tables to SRAM to use bcc_set_trap() at run time. &lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 4 – Timer interrupt starts task&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- =&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
In common situation embedded application would call list of functions in a while loop and interrupt service routines are used for critical operations.&amp;lt;br&amp;gt;&lt;br /&gt;
Using RTOS for the same application would make developers life easier and would save power consumption. &lt;br /&gt;
Each function in a list of while loop can represent the task and started only when something really happen. Most of RTOS available today would use priority controlled round-robin scheduling. Where the tasks require different response time developer could assigned different priorities for those tasks and scheduling according to those priorities. Tasks with the same priorities are scheduled using round-robin.&lt;br /&gt;
&lt;br /&gt;
This is where OCEOS is different. &lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_fdir&amp;diff=1489</id>
		<title>OCEOS/oceos fdir</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_fdir&amp;diff=1489"/>
		<updated>2022-04-11T11:49:28Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* FDIR Configuration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS  Fault Detection, Isolation and Recovery (FDIR)'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
==&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;FDIR Introduction&amp;lt;/span&amp;gt;==&lt;br /&gt;
Hardware and software faults can occur that affect the behavior of the system. To detect such faults and anomalies, as scheduling proceeds OCEOS automatically checks that its key data areas have not been corrupted and that uses of resources are within their prescribed bounds. Parameters passed to directives are checked for consistency with the values originally declared in the application configuration.&amp;lt;br&amp;gt;&lt;br /&gt;
Once detected, OCEOS provides five levels of responses to faults and anomalies:&amp;lt;br&amp;gt;&lt;br /&gt;
'''Level 1''': The status code returned by a directive indicates that there was a problem&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The status code returned by a directive should always be checked.&amp;lt;br&amp;gt;&lt;br /&gt;
This code identifies whether the directive succeeded and if not indicates the reason for the failure.&amp;lt;br&amp;gt;&lt;br /&gt;
This is the only response made when the anomaly is an invalid parameter to a directive. It is combined with responses from other levels if a directive fails for some other reason.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
'''Level 2''': An appropriate log entry is added to the system log.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The log entry contains a code identifying the problem and a 32-bit timestamp.&amp;lt;br&amp;gt;&lt;br /&gt;
This response occurs in addition to the Level 1 response if a directive fails due to an internal factor such as the maximum number of jobs for a task being already created or a data queue being full.&amp;lt;br&amp;gt;&lt;br /&gt;
This response also occurs when a task misses its deadline or any unexpected behavior. This response is often accompanied by a Level 3 response.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
'''Level 3''': The system state variable is updated and a user defined problem handling function called.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The system state variable consists of 32 flags each indicating a particular problem type. It is reset by [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]]. A copy of this variable is also maintained. Both variables may be reset by the ASW.&lt;br /&gt;
This response occurs also in most circumstances where the Level 2 response occurs.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
'''Level 4''': An ASW problem handling function is called by OCEOS.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
A problem handling function can be identified in the application configuration structure passed to [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] and if present may be called by OCEOS.&lt;br /&gt;
This function can read the system log and system state variable, read the task timing and other information, enable and disable tasks, reset counting semaphores and data queues, and if necessary exit OCEOS. It can reset the system state variable, it is recommended that the copy of the system state variable not be reset so as to provide a longer term record of problems.&amp;lt;br&amp;gt;&lt;br /&gt;
This response occurs also in most circumstances where the Level 3 response occurs&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
'''Level 5''': OCEOS exits and returns to the ASW with an appropriate status code.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The status code in effect provides a Level 1 response to the [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] directive used by the ASW to start OCEOS. In normal circumstances OCEOS never returns to the ASW.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
This response by OCEOS only occurs when it detects that one of its essential internal elements has been corrupted. Depending on the severity of this corruption a Level 2 response may also be provided if possible, and the system state variable may also be updated. The user defined problem handling function is not called.&lt;br /&gt;
&lt;br /&gt;
If OCEOS exits the ASW can inspect the system log and system status variable, and also the task timings and other information maintained by OCEOS. The ASW can decide what corrective action should be taken and may resume scheduling with a call to [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The ASW can also inspect these items during scheduling, allowing it check the state of the system at any time.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This approach provides a graduated response by OCEOS to problems and allows some problems be isolated and recovered by, for example, disabling tasks or clearing a data queue if an appropriate problem handling function is provided as part of the ASW. The ASW may also check system information at any time to determine whether things are proceeding as expected.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
The ASW may set up a watchdog timer which will cause a system reset if a certain time elapses before it is reset. By using a lowest priority task to reset the watchdog failure of higher priority tasks to complete within their expected time can be detected. In OCEOS the lowest priority task, if it is the only task at that priority, is allowed to run forever and may be used to reset the watchdog. &amp;lt;br&amp;gt;&lt;br /&gt;
OCEOS provides watchdog timer functionality for GR716 target and not part of OCEOS for other targets.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
The log area contains the System State Variable, the system log, and the optional context switch log.&lt;br /&gt;
&lt;br /&gt;
The OCEOS system state variable contains flags that indicate a certain problem has occurred. It is automatically updated by OCEOS using ‘OR’ to avoiding losing information, typically a user defined function is called to deal with the problem.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Two sets of flags are kept as part of the system state variable. One accumulates indicators of all problems that have occurred, and typically is reset by the application only after a restart. The other indicates current problems, and typically is reset by the user defined problem handling function. For system state variable location please see [[OCEOS/oceos introduction#OCEOS_Data_Area_Layouts|HERE]].&amp;lt;br&amp;gt;&lt;br /&gt;
Application developer can provide system status mask that is used to AND with system status variable and if not zero, calls user defined error handling function. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *&lt;br /&gt;
 * SYSTEM STATUS VARIABLE FLAGS&lt;br /&gt;
 *&lt;br /&gt;
 * These are stored in the 32-bit system status variable &lt;br /&gt;
 * and updated by OCEOS when a problem is detected.&lt;br /&gt;
 * Resetting them is the responsibility of the application.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#define  STATUS_NORMAL                   0U    // no flag set&lt;br /&gt;
#define  STATUS_MASK_NORMAL            0x0U    // no error function can be called&lt;br /&gt;
#define  STATUS_INVALID         0xffffffffU    // system status invalid&lt;br /&gt;
&lt;br /&gt;
/* Task related problems */&lt;br /&gt;
#define  STATUS_DISABLED_TASK_START    0x1U    // An attempt to start a disabled task&lt;br /&gt;
#define  STATUS_TASK_JOB_LIMIT_OVER    0x2U    // An attempt to execute a task when its jobs limit is already reached.&lt;br /&gt;
#define  STATUS_JOB_OVER_TIME          0x4U    // Job time from creation to completion exceeds allowed maximum for task&lt;br /&gt;
#define  STATUS_JOB_INTERVAL_SHORT     0x8U    // Minimum time between job creations is less than the allowed minimum for task&lt;br /&gt;
#define  STATUS_READYQ_FULL           0x10U    // Ready queue unable to accept job as result of being full&lt;br /&gt;
#define  STATUS_READYQ_NO_REMOVE      0x20U    // Remove job from ready queue failed&lt;br /&gt;
&lt;br /&gt;
/* Mutex related problems */&lt;br /&gt;
#define  STATUS_MUTEX_ALREADY_HELD    0x40U    // Mutex wait() when mutex already held&lt;br /&gt;
#define  STATUS_MUTEX_NOT_HELD        0x80U    // Mutex signal() when not already held&lt;br /&gt;
#define  STATUS_MUTEX_NOT_RETURNED   0x100U    // Mutex not returned before job terminates&lt;br /&gt;
#define  STATUS_MUTEX_NOT_NESTED     0x200U    // Use of multiple mutexes not nested&lt;br /&gt;
&lt;br /&gt;
/* Counting semaphore and data queue related problems */&lt;br /&gt;
#define  STATUS_SEMAPHORE_JOBS_FULL  0x400U    // Attempt to add job to semaphore pending list when list full&lt;br /&gt;
#define  STATUS_DATAQ_JOBS_FULL      0x800U    // Attempt to add job to data queue pending list when list full&lt;br /&gt;
#define  STATUS_DATAQ_FULL          0x1000U    // Data queue write when queue already full&lt;br /&gt;
&lt;br /&gt;
/* Timed actions related problems */&lt;br /&gt;
#define  STATUS_TIMED_JOBS_FULL     0x2000U    // Timed actions queue already full for timed task start&lt;br /&gt;
#define  STATUS_TIMED_OUTPUT_FULL   0x4000U    // Timed actions queue already full for timed output&lt;br /&gt;
#define  STATUS_TIMED_ACTION_LATE   0x8000U    // Timed action late&lt;br /&gt;
&lt;br /&gt;
/* Default trap handler should have been replaced&lt;br /&gt;
 * NOT USED AT THE MOMENT*/&lt;br /&gt;
#define  STATUS_SYSTEM_ERROR       0x10000U    // ERROR was handled by default trap handler&lt;br /&gt;
&lt;br /&gt;
/* Flag to indicate problem with Stack Pointe&lt;br /&gt;
 * NOT USED AT THE MOMENT*/&lt;br /&gt;
#define  STATUS_SP_WARNING         0x20000U    // SP not in expected range&lt;br /&gt;
/* Log system error */&lt;br /&gt;
#define  STATUS_BAD_LOG            0x40000U    // System log problem&lt;br /&gt;
&lt;br /&gt;
/* Not using next few bits */&lt;br /&gt;
&lt;br /&gt;
/* Will have to exit */&lt;br /&gt;
#define  STATUS_BAD_SENTINEL    0x40000000U    // Area sentinel corrupt&lt;br /&gt;
#define  STATUS_BAD_META_PTR    0x80000000U    // Null meta pointer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;FDIR Configuration&amp;lt;/span&amp;gt;==&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
User can provide function, that is called in case of system ERROR&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  //  Application ERROR Handling code&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
/*&lt;br /&gt;
 * Create the application configuration structure&lt;br /&gt;
 */&lt;br /&gt;
struct application_configuration           app_config = {0};&lt;br /&gt;
app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;API Functions&amp;lt;/span&amp;gt;==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ API Functions&lt;br /&gt;
|-&lt;br /&gt;
! Directive                                                                                           !! Description                                 !! main !! task !! IRQ handler&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_state_get()|oceos_system_state_get()]]                              || Get the value of the system state variable  ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_state_set()|oceos_system_state_set()]]                              || Set system state variable                   ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_watchdog_init()|oceos_system_watchdog_init()]]                      || Initialize the watchdog                     ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_watchdog_enable()|oceos_system_watchdog_enable()]]                  || Enable the watchdog                         ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_watchdog_disable()|oceos_system_watchdog_disable()]]                || Disable the watchdog                        ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_watchdog_ticks_remaining()|oceos_system_watchdog_ticks_remaining()]]|| Get the number of ticks to watchdog timeout ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_watchdog_reset()|oceos_system_watchdog_reset()]]                    || Reset the watchdog                          ||  *   ||  *   || *&lt;br /&gt;
|}&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_state_get()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''system_log.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns the value of the system state variable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
U32_t                   oceos_system_state_get(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
|  ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns U32_t.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! U32_t !! Description&lt;br /&gt;
|-&lt;br /&gt;
| STATUS_INVALID || Failed to read System State Status&lt;br /&gt;
|-&lt;br /&gt;
| &amp;gt;= 0   || System State Status&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
 U32_t status;&lt;br /&gt;
 status = oceos_system_state_get();&lt;br /&gt;
 if (STATUS_INVALID == status) {&lt;br /&gt;
   // Handle ERROR&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_state_set()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''system_log.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Set system state variable and save previous setting to System State variable OLD. Setting to zero means resetting the System State status&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS   oceos_system_state_set(&lt;br /&gt;
    U32_t new_state              // new value of system state variable&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| new_state || New value of system state variable&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns enum DIRECTIVE_STATUS.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! enum DIRECTIVE_STATUS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| INCORRECT_STATE || System Meta pointer is NULL or Log pointer is NULL&lt;br /&gt;
|-&lt;br /&gt;
| SUCCESSFUL      || All OK&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS status;&lt;br /&gt;
U32_t sys_state = 0;&lt;br /&gt;
status = oceos_system_state_set(sys_state);&lt;br /&gt;
if (SUCCESSFUL != status) {&lt;br /&gt;
  // Handle ERROR&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_watchdog_init()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''FDIR.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''FOR GR716 ONLY'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This directive initializes the watchdog for GR716 at 0x80003070. The watchdog window reload value is in the control register. Large window sizes make resets more likely.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS   oceos_system_watchdog_init(&lt;br /&gt;
    BOOLE_t enable,            // enabled initially&lt;br /&gt;
    U32_t timeout,             // watchdog timeout&lt;br /&gt;
    U8_t window_size           // watchdog window&lt;br /&gt;
 );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| enable      || TRUE to enable watchdog at initialization&lt;br /&gt;
|-&lt;br /&gt;
| timeout     || Watchdog timeout&lt;br /&gt;
|-&lt;br /&gt;
| window_size || Watchdog windows size&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns enum DIRECTIVE_STATUS.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! enum DIRECTIVE_STATUS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| INVALID_NUMBER  || Parameter check failed&lt;br /&gt;
|-&lt;br /&gt;
| SUCCESSFUL      || All OK&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
 enum DIRECTIVE_STATUS status;&lt;br /&gt;
 status = oceos_system_watchdog_init(TRUE, 1000, 0xFF);&lt;br /&gt;
 if (SUCCESSFUL != status) {&lt;br /&gt;
   // Handle ERROR&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_watchdog_enable()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''FDIR.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''FOR GR716 ONLY'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This directive enables the watchdog for GR716 at 0x80003070 which will use timeout and window values setup previously.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS  oceos_system_watchdog_enable();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
|  ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns enum DIRECTIVE_STATUS.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! enum DIRECTIVE_STATUS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| SUCCESSFUL     || All OK&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS status;&lt;br /&gt;
status = oceos_system_watchdog_enable();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_watchdog_disable()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''FDIR.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''FOR GR716 ONLY'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This directive disables the watchdog for GR716 at 0x80003070.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS  oceos_system_watchdog_disable();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
|  ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns enum DIRECTIVE_STATUS.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! enum DIRECTIVE_STATUS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| SUCCESSFUL     || All OK&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS status;&lt;br /&gt;
status = oceos_system_watchdog_disable();    &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_watchdog_ticks_remaining()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''FDIR.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''FOR GR716 ONLY'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This directive returns number of ticks remaining in watchdog timer for GR716 at 0x80003070.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
unsigned int  oceos_system_watchdog_ticks_remaining();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
|  ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns unsigned int.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! unsigned int !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;gt;= 0 || Number of watchdog ticks &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
unsigned int num_ticks;&lt;br /&gt;
num_ticks = oceos_system_watchdog_ticks_remaining();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_watchdog_reset()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''FDIR.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''FOR GR716 ONLY'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This directive resets the watchdog timer for GR716 at 0x80003070, allowing it to be enabled or disabled after reset.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS  oceos_system_watchdog_reset(&lt;br /&gt;
    BOOLE_t enable     // whether to enable or disable after reset&lt;br /&gt;
 );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| enable || Whether to enable or disable after reset&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns enum DIRECTIVE_STATUS.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! enum DIRECTIVE_STATUS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| SUCCESSFUL     || All OK&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
 enum DIRECTIVE_STATUS status;&lt;br /&gt;
 status = oceos_system_watchdog_reset(TRUE);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_fdir&amp;diff=1488</id>
		<title>OCEOS/oceos fdir</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_fdir&amp;diff=1488"/>
		<updated>2022-04-08T10:06:14Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* FDIR Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS  Fault Detection, Isolation and Recovery (FDIR)'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
==&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;FDIR Introduction&amp;lt;/span&amp;gt;==&lt;br /&gt;
Hardware and software faults can occur that affect the behavior of the system. To detect such faults and anomalies, as scheduling proceeds OCEOS automatically checks that its key data areas have not been corrupted and that uses of resources are within their prescribed bounds. Parameters passed to directives are checked for consistency with the values originally declared in the application configuration.&amp;lt;br&amp;gt;&lt;br /&gt;
Once detected, OCEOS provides five levels of responses to faults and anomalies:&amp;lt;br&amp;gt;&lt;br /&gt;
'''Level 1''': The status code returned by a directive indicates that there was a problem&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The status code returned by a directive should always be checked.&amp;lt;br&amp;gt;&lt;br /&gt;
This code identifies whether the directive succeeded and if not indicates the reason for the failure.&amp;lt;br&amp;gt;&lt;br /&gt;
This is the only response made when the anomaly is an invalid parameter to a directive. It is combined with responses from other levels if a directive fails for some other reason.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
'''Level 2''': An appropriate log entry is added to the system log.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The log entry contains a code identifying the problem and a 32-bit timestamp.&amp;lt;br&amp;gt;&lt;br /&gt;
This response occurs in addition to the Level 1 response if a directive fails due to an internal factor such as the maximum number of jobs for a task being already created or a data queue being full.&amp;lt;br&amp;gt;&lt;br /&gt;
This response also occurs when a task misses its deadline or any unexpected behavior. This response is often accompanied by a Level 3 response.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
'''Level 3''': The system state variable is updated and a user defined problem handling function called.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The system state variable consists of 32 flags each indicating a particular problem type. It is reset by [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]]. A copy of this variable is also maintained. Both variables may be reset by the ASW.&lt;br /&gt;
This response occurs also in most circumstances where the Level 2 response occurs.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
'''Level 4''': An ASW problem handling function is called by OCEOS.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
A problem handling function can be identified in the application configuration structure passed to [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] and if present may be called by OCEOS.&lt;br /&gt;
This function can read the system log and system state variable, read the task timing and other information, enable and disable tasks, reset counting semaphores and data queues, and if necessary exit OCEOS. It can reset the system state variable, it is recommended that the copy of the system state variable not be reset so as to provide a longer term record of problems.&amp;lt;br&amp;gt;&lt;br /&gt;
This response occurs also in most circumstances where the Level 3 response occurs&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
'''Level 5''': OCEOS exits and returns to the ASW with an appropriate status code.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The status code in effect provides a Level 1 response to the [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] directive used by the ASW to start OCEOS. In normal circumstances OCEOS never returns to the ASW.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
This response by OCEOS only occurs when it detects that one of its essential internal elements has been corrupted. Depending on the severity of this corruption a Level 2 response may also be provided if possible, and the system state variable may also be updated. The user defined problem handling function is not called.&lt;br /&gt;
&lt;br /&gt;
If OCEOS exits the ASW can inspect the system log and system status variable, and also the task timings and other information maintained by OCEOS. The ASW can decide what corrective action should be taken and may resume scheduling with a call to [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The ASW can also inspect these items during scheduling, allowing it check the state of the system at any time.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This approach provides a graduated response by OCEOS to problems and allows some problems be isolated and recovered by, for example, disabling tasks or clearing a data queue if an appropriate problem handling function is provided as part of the ASW. The ASW may also check system information at any time to determine whether things are proceeding as expected.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
The ASW may set up a watchdog timer which will cause a system reset if a certain time elapses before it is reset. By using a lowest priority task to reset the watchdog failure of higher priority tasks to complete within their expected time can be detected. In OCEOS the lowest priority task, if it is the only task at that priority, is allowed to run forever and may be used to reset the watchdog. &amp;lt;br&amp;gt;&lt;br /&gt;
OCEOS provides watchdog timer functionality for GR716 target and not part of OCEOS for other targets.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
The log area contains the System State Variable, the system log, and the optional context switch log.&lt;br /&gt;
&lt;br /&gt;
The OCEOS system state variable contains flags that indicate a certain problem has occurred. It is automatically updated by OCEOS using ‘OR’ to avoiding losing information, typically a user defined function is called to deal with the problem.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Two sets of flags are kept as part of the system state variable. One accumulates indicators of all problems that have occurred, and typically is reset by the application only after a restart. The other indicates current problems, and typically is reset by the user defined problem handling function. For system state variable location please see [[OCEOS/oceos introduction#OCEOS_Data_Area_Layouts|HERE]].&amp;lt;br&amp;gt;&lt;br /&gt;
Application developer can provide system status mask that is used to AND with system status variable and if not zero, calls user defined error handling function. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *&lt;br /&gt;
 * SYSTEM STATUS VARIABLE FLAGS&lt;br /&gt;
 *&lt;br /&gt;
 * These are stored in the 32-bit system status variable &lt;br /&gt;
 * and updated by OCEOS when a problem is detected.&lt;br /&gt;
 * Resetting them is the responsibility of the application.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#define  STATUS_NORMAL                   0U    // no flag set&lt;br /&gt;
#define  STATUS_MASK_NORMAL            0x0U    // no error function can be called&lt;br /&gt;
#define  STATUS_INVALID         0xffffffffU    // system status invalid&lt;br /&gt;
&lt;br /&gt;
/* Task related problems */&lt;br /&gt;
#define  STATUS_DISABLED_TASK_START    0x1U    // An attempt to start a disabled task&lt;br /&gt;
#define  STATUS_TASK_JOB_LIMIT_OVER    0x2U    // An attempt to execute a task when its jobs limit is already reached.&lt;br /&gt;
#define  STATUS_JOB_OVER_TIME          0x4U    // Job time from creation to completion exceeds allowed maximum for task&lt;br /&gt;
#define  STATUS_JOB_INTERVAL_SHORT     0x8U    // Minimum time between job creations is less than the allowed minimum for task&lt;br /&gt;
#define  STATUS_READYQ_FULL           0x10U    // Ready queue unable to accept job as result of being full&lt;br /&gt;
#define  STATUS_READYQ_NO_REMOVE      0x20U    // Remove job from ready queue failed&lt;br /&gt;
&lt;br /&gt;
/* Mutex related problems */&lt;br /&gt;
#define  STATUS_MUTEX_ALREADY_HELD    0x40U    // Mutex wait() when mutex already held&lt;br /&gt;
#define  STATUS_MUTEX_NOT_HELD        0x80U    // Mutex signal() when not already held&lt;br /&gt;
#define  STATUS_MUTEX_NOT_RETURNED   0x100U    // Mutex not returned before job terminates&lt;br /&gt;
#define  STATUS_MUTEX_NOT_NESTED     0x200U    // Use of multiple mutexes not nested&lt;br /&gt;
&lt;br /&gt;
/* Counting semaphore and data queue related problems */&lt;br /&gt;
#define  STATUS_SEMAPHORE_JOBS_FULL  0x400U    // Attempt to add job to semaphore pending list when list full&lt;br /&gt;
#define  STATUS_DATAQ_JOBS_FULL      0x800U    // Attempt to add job to data queue pending list when list full&lt;br /&gt;
#define  STATUS_DATAQ_FULL          0x1000U    // Data queue write when queue already full&lt;br /&gt;
&lt;br /&gt;
/* Timed actions related problems */&lt;br /&gt;
#define  STATUS_TIMED_JOBS_FULL     0x2000U    // Timed actions queue already full for timed task start&lt;br /&gt;
#define  STATUS_TIMED_OUTPUT_FULL   0x4000U    // Timed actions queue already full for timed output&lt;br /&gt;
#define  STATUS_TIMED_ACTION_LATE   0x8000U    // Timed action late&lt;br /&gt;
&lt;br /&gt;
/* Default trap handler should have been replaced&lt;br /&gt;
 * NOT USED AT THE MOMENT*/&lt;br /&gt;
#define  STATUS_SYSTEM_ERROR       0x10000U    // ERROR was handled by default trap handler&lt;br /&gt;
&lt;br /&gt;
/* Flag to indicate problem with Stack Pointe&lt;br /&gt;
 * NOT USED AT THE MOMENT*/&lt;br /&gt;
#define  STATUS_SP_WARNING         0x20000U    // SP not in expected range&lt;br /&gt;
/* Log system error */&lt;br /&gt;
#define  STATUS_BAD_LOG            0x40000U    // System log problem&lt;br /&gt;
&lt;br /&gt;
/* Not using next few bits */&lt;br /&gt;
&lt;br /&gt;
/* Will have to exit */&lt;br /&gt;
#define  STATUS_BAD_SENTINEL    0x40000000U    // Area sentinel corrupt&lt;br /&gt;
#define  STATUS_BAD_META_PTR    0x80000000U    // Null meta pointer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;FDIR Configuration&amp;lt;/span&amp;gt;==&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
User can provide function, that is called in case of system ERROR&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  //  Application ERROR Handling code&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
/*&lt;br /&gt;
 * Create the application configuration structure&lt;br /&gt;
 */&lt;br /&gt;
struct application_configuration           app_config = {0};&lt;br /&gt;
app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;API Functions&amp;lt;/span&amp;gt;==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ API Functions&lt;br /&gt;
|-&lt;br /&gt;
! Directive                                                                                           !! Description                                 !! main !! task !! IRQ handler&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_state_get()|oceos_system_state_get()]]                              || Get the value of the system state variable  ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_state_set()|oceos_system_state_set()]]                              || Set system state variable                   ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_watchdog_init()|oceos_system_watchdog_init()]]                      || Initialize the watchdog                     ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_watchdog_enable()|oceos_system_watchdog_enable()]]                  || Enable the watchdog                         ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_watchdog_disable()|oceos_system_watchdog_disable()]]                || Disable the watchdog                        ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_watchdog_ticks_remaining()|oceos_system_watchdog_ticks_remaining()]]|| Get the number of ticks to watchdog timeout ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_watchdog_reset()|oceos_system_watchdog_reset()]]                    || Reset the watchdog                          ||  *   ||  *   || *&lt;br /&gt;
|}&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_state_get()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''system_log.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns the value of the system state variable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
U32_t                   oceos_system_state_get(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
|  ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns U32_t.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! U32_t !! Description&lt;br /&gt;
|-&lt;br /&gt;
| STATUS_INVALID || Failed to read System State Status&lt;br /&gt;
|-&lt;br /&gt;
| &amp;gt;= 0   || System State Status&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
 U32_t status;&lt;br /&gt;
 status = oceos_system_state_get();&lt;br /&gt;
 if (STATUS_INVALID == status) {&lt;br /&gt;
   // Handle ERROR&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_state_set()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''system_log.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Set system state variable and save previous setting to System State variable OLD. Setting to zero means resetting the System State status&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS   oceos_system_state_set(&lt;br /&gt;
    U32_t new_state              // new value of system state variable&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| new_state || New value of system state variable&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns enum DIRECTIVE_STATUS.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! enum DIRECTIVE_STATUS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| INCORRECT_STATE || System Meta pointer is NULL or Log pointer is NULL&lt;br /&gt;
|-&lt;br /&gt;
| SUCCESSFUL      || All OK&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS status;&lt;br /&gt;
U32_t sys_state = 0;&lt;br /&gt;
status = oceos_system_state_set(sys_state);&lt;br /&gt;
if (SUCCESSFUL != status) {&lt;br /&gt;
  // Handle ERROR&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_watchdog_init()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''FDIR.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''FOR GR716 ONLY'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This directive initializes the watchdog for GR716 at 0x80003070. The watchdog window reload value is in the control register. Large window sizes make resets more likely.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS   oceos_system_watchdog_init(&lt;br /&gt;
    BOOLE_t enable,            // enabled initially&lt;br /&gt;
    U32_t timeout,             // watchdog timeout&lt;br /&gt;
    U8_t window_size           // watchdog window&lt;br /&gt;
 );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| enable      || TRUE to enable watchdog at initialization&lt;br /&gt;
|-&lt;br /&gt;
| timeout     || Watchdog timeout&lt;br /&gt;
|-&lt;br /&gt;
| window_size || Watchdog windows size&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns enum DIRECTIVE_STATUS.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! enum DIRECTIVE_STATUS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| INVALID_NUMBER  || Parameter check failed&lt;br /&gt;
|-&lt;br /&gt;
| SUCCESSFUL      || All OK&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
 enum DIRECTIVE_STATUS status;&lt;br /&gt;
 status = oceos_system_watchdog_init(TRUE, 1000, 0xFF);&lt;br /&gt;
 if (SUCCESSFUL != status) {&lt;br /&gt;
   // Handle ERROR&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_watchdog_enable()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''FDIR.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''FOR GR716 ONLY'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This directive enables the watchdog for GR716 at 0x80003070 which will use timeout and window values setup previously.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS  oceos_system_watchdog_enable();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
|  ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns enum DIRECTIVE_STATUS.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! enum DIRECTIVE_STATUS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| SUCCESSFUL     || All OK&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS status;&lt;br /&gt;
status = oceos_system_watchdog_enable();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_watchdog_disable()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''FDIR.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''FOR GR716 ONLY'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This directive disables the watchdog for GR716 at 0x80003070.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS  oceos_system_watchdog_disable();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
|  ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns enum DIRECTIVE_STATUS.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! enum DIRECTIVE_STATUS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| SUCCESSFUL     || All OK&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS status;&lt;br /&gt;
status = oceos_system_watchdog_disable();    &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_watchdog_ticks_remaining()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''FDIR.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''FOR GR716 ONLY'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This directive returns number of ticks remaining in watchdog timer for GR716 at 0x80003070.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
unsigned int  oceos_system_watchdog_ticks_remaining();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
|  ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns unsigned int.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! unsigned int !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;gt;= 0 || Number of watchdog ticks &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
unsigned int num_ticks;&lt;br /&gt;
num_ticks = oceos_system_watchdog_ticks_remaining();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_watchdog_reset()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''FDIR.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''FOR GR716 ONLY'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This directive resets the watchdog timer for GR716 at 0x80003070, allowing it to be enabled or disabled after reset.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS  oceos_system_watchdog_reset(&lt;br /&gt;
    BOOLE_t enable     // whether to enable or disable after reset&lt;br /&gt;
 );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| enable || Whether to enable or disable after reset&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns enum DIRECTIVE_STATUS.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! enum DIRECTIVE_STATUS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| SUCCESSFUL     || All OK&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
 enum DIRECTIVE_STATUS status;&lt;br /&gt;
 status = oceos_system_watchdog_reset(TRUE);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_fdir&amp;diff=1487</id>
		<title>OCEOS/oceos fdir</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_fdir&amp;diff=1487"/>
		<updated>2022-04-08T10:05:40Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* FDIR Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS  Fault Detection, Isolation and Recovery (FDIR)'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
==&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;FDIR Introduction&amp;lt;/span&amp;gt;==&lt;br /&gt;
Hardware and software faults can occur that affect the behavior of the system. To detect such faults and anomalies, as scheduling proceeds OCEOS automatically checks that its key data areas have not been corrupted and that uses of resources are within their prescribed bounds. Parameters passed to directives are checked for consistency with the values originally declared in the application configuration.&amp;lt;br&amp;gt;&lt;br /&gt;
Once detected, OCEOS provides five levels of responses to faults and anomalies:&amp;lt;br&amp;gt;&lt;br /&gt;
'''Level 1''': The status code returned by a directive indicates that there was a problem&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The status code returned by a directive should always be checked.&amp;lt;br&amp;gt;&lt;br /&gt;
This code identifies whether the directive succeeded and if not indicates the reason for the failure.&amp;lt;br&amp;gt;&lt;br /&gt;
This is the only response made when the anomaly is an invalid parameter to a directive. It is combined with responses from other levels if a directive fails for some other reason.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
'''Level 2''': An appropriate log entry is added to the system log.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The log entry contains a code identifying the problem and a 32-bit timestamp.&amp;lt;br&amp;gt;&lt;br /&gt;
This response occurs in addition to the Level 1 response if a directive fails due to an internal factor such as the maximum number of jobs for a task being already created or a data queue being full.&amp;lt;br&amp;gt;&lt;br /&gt;
This response also occurs when a task misses its deadline or any unexpected behavior. This response is often accompanied by a Level 3 response.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
'''Level 3''': The system state variable is updated and a user defined problem handling function called.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The system state variable consists of 32 flags each indicating a particular problem type. It is reset by [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]]. A copy of this variable is also maintained. Both variables may be reset by the ASW.&lt;br /&gt;
This response occurs also in most circumstances where the Level 2 response occurs.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
'''Level 4''': An ASW problem handling function is called by OCEOS.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
A problem handling function can be identified in the application configuration structure passed to [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] and if present may be called by OCEOS.&lt;br /&gt;
This function can read the system log and system state variable, read the task timing and other information, enable and disable tasks, reset counting semaphores and data queues, and if necessary exit OCEOS. It can reset the system state variable, it is recommended that the copy of the system state variable not be reset so as to provide a longer term record of problems.&amp;lt;br&amp;gt;&lt;br /&gt;
This response occurs also in most circumstances where the Level 3 response occurs&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
'''Level 5''': OCEOS exits and returns to the ASW with an appropriate status code.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The status code in effect provides a Level 1 response to the [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] directive used by the ASW to start OCEOS. In normal circumstances OCEOS never returns to the ASW.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
This response by OCEOS only occurs when it detects that one of its essential internal elements has been corrupted. Depending on the severity of this corruption a Level 2 response may also be provided if possible, and the system state variable may also be updated. The user defined problem handling function is not called.&lt;br /&gt;
&lt;br /&gt;
If OCEOS exits the ASW can inspect the system log and system status variable, and also the task timings and other information maintained by OCEOS. The ASW can decide what corrective action should be taken and may resume scheduling with a call to [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The ASW can also inspect these items during scheduling, allowing it check the state of the system at any time.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This approach provides a graduated response by OCEOS to problems and allows some problems be isolated and recovered by, for example, disabling tasks or clearing a data queue if an appropriate problem handling function is provided as part of the ASW. The ASW may also check system information at any time to determine whether things are proceeding as expected.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
The ASW may set up a watchdog timer which will cause a system reset if a certain time elapses before it is reset. By using a lowest priority task to reset the watchdog failure of higher priority tasks to complete within their expected time can be detected. In OCEOS the lowest priority task, if it is the only task at that priority, is allowed to run forever and may be used to reset the watchdog. &amp;lt;br&amp;gt;&lt;br /&gt;
OCEOS provides watchdog timer functionality for GR716 target and not part of OCEOS for other targets.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
The log area contains the System State Variable, the system log, and the optional context switch log.&lt;br /&gt;
&lt;br /&gt;
The OCEOS system state variable contains flags that indicate a certain problem has occurred. It is automatically updated by OCEOS using ‘OR’ to avoiding losing information, typically a user defined function is called to deal with the problem.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Two sets of flags are kept as part of the system state variable. One accumulates indicators of all problems that have occurred, and typically is reset by the application only after a restart. The other indicates current problems, and typically is reset by the user defined problem handling function. For system state variable location please see [[OCEOS/oceos introduction#OCEOS_Data_Area_Layouts|HERE]].&amp;lt;br&amp;gt;&lt;br /&gt;
Application developer can provide system status mask that is used to AND with system status variable and if not zero, calls user defined error handling function. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *&lt;br /&gt;
 * SYSTEM STATUS VARIABLE FLAGS&lt;br /&gt;
 *&lt;br /&gt;
 * These are stored in the 32-bit system status variable &lt;br /&gt;
 * and updated by OCEOS when a problem is detected.&lt;br /&gt;
 * Resetting them is the responsibility of the application.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#define  STATUS_NORMAL                   0U    // no flag set&lt;br /&gt;
#define  STATUS_MASK_NORMAL            0x0U    // no error function can be called&lt;br /&gt;
#define  STATUS_INVALID         0xffffffffU    // system status invalid&lt;br /&gt;
&lt;br /&gt;
/* Task related problems */&lt;br /&gt;
#define  STATUS_DISABLED_TASK_START    0x1U    // An attempt to start a disabled task&lt;br /&gt;
#define  STATUS_TASK_JOB_LIMIT_OVER    0x2U    // An attempt to execute a task when its jobs limit is already reached.&lt;br /&gt;
#define  STATUS_JOB_OVER_TIME          0x4U    // Job time from creation to completion exceeds allowed maximum for task. YES&lt;br /&gt;
#define  STATUS_JOB_INTERVAL_SHORT     0x8U    // Minimum time between job creations is less than the allowed minimum for task&lt;br /&gt;
#define  STATUS_READYQ_FULL           0x10U    // Ready queue unable to accept job as result of being full&lt;br /&gt;
#define  STATUS_READYQ_NO_REMOVE      0x20U    // Remove job from ready queue failed&lt;br /&gt;
&lt;br /&gt;
/* Mutex related problems */&lt;br /&gt;
#define  STATUS_MUTEX_ALREADY_HELD    0x40U    // Mutex wait() when mutex already held&lt;br /&gt;
#define  STATUS_MUTEX_NOT_HELD        0x80U    // Mutex signal() when not already held&lt;br /&gt;
#define  STATUS_MUTEX_NOT_RETURNED   0x100U    // Mutex not returned before job terminates&lt;br /&gt;
#define  STATUS_MUTEX_NOT_NESTED     0x200U    // Use of multiple mutexes not nested&lt;br /&gt;
&lt;br /&gt;
/* Counting semaphore and data queue related problems */&lt;br /&gt;
#define  STATUS_SEMAPHORE_JOBS_FULL  0x400U    // Attempt to add job to semaphore pending list when list full&lt;br /&gt;
#define  STATUS_DATAQ_JOBS_FULL      0x800U    // Attempt to add job to data queue pending list when list full&lt;br /&gt;
#define  STATUS_DATAQ_FULL          0x1000U    // Data queue write when queue already full&lt;br /&gt;
&lt;br /&gt;
/* Timed actions related problems */&lt;br /&gt;
#define  STATUS_TIMED_JOBS_FULL     0x2000U    // Timed actions queue already full for timed task start&lt;br /&gt;
#define  STATUS_TIMED_OUTPUT_FULL   0x4000U    // Timed actions queue already full for timed output&lt;br /&gt;
#define  STATUS_TIMED_ACTION_LATE   0x8000U    // Timed action late                          YES&lt;br /&gt;
&lt;br /&gt;
/* Default trap handler should have been replaced&lt;br /&gt;
 * NOT USED AT THE MOMENT*/&lt;br /&gt;
#define  STATUS_SYSTEM_ERROR       0x10000U    // ERROR was handled by default trap handler  YES&lt;br /&gt;
&lt;br /&gt;
/* Flag to indicate problem with Stack Pointe&lt;br /&gt;
 * NOT USED AT THE MOMENT*/&lt;br /&gt;
#define  STATUS_SP_WARNING         0x20000U    // SP not in expected range&lt;br /&gt;
/* Log system error */&lt;br /&gt;
#define  STATUS_BAD_LOG            0x40000U    // System log problem&lt;br /&gt;
&lt;br /&gt;
/* Not using next few bits */&lt;br /&gt;
&lt;br /&gt;
/* Will have to exit */&lt;br /&gt;
#define  STATUS_BAD_SENTINEL    0x40000000U    // Area sentinel corrupt&lt;br /&gt;
#define  STATUS_BAD_META_PTR    0x80000000U    // Null meta pointer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;FDIR Configuration&amp;lt;/span&amp;gt;==&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
User can provide function, that is called in case of system ERROR&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  //  Application ERROR Handling code&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
/*&lt;br /&gt;
 * Create the application configuration structure&lt;br /&gt;
 */&lt;br /&gt;
struct application_configuration           app_config = {0};&lt;br /&gt;
app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;API Functions&amp;lt;/span&amp;gt;==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ API Functions&lt;br /&gt;
|-&lt;br /&gt;
! Directive                                                                                           !! Description                                 !! main !! task !! IRQ handler&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_state_get()|oceos_system_state_get()]]                              || Get the value of the system state variable  ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_state_set()|oceos_system_state_set()]]                              || Set system state variable                   ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_watchdog_init()|oceos_system_watchdog_init()]]                      || Initialize the watchdog                     ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_watchdog_enable()|oceos_system_watchdog_enable()]]                  || Enable the watchdog                         ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_watchdog_disable()|oceos_system_watchdog_disable()]]                || Disable the watchdog                        ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_watchdog_ticks_remaining()|oceos_system_watchdog_ticks_remaining()]]|| Get the number of ticks to watchdog timeout ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_watchdog_reset()|oceos_system_watchdog_reset()]]                    || Reset the watchdog                          ||  *   ||  *   || *&lt;br /&gt;
|}&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_state_get()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''system_log.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns the value of the system state variable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
U32_t                   oceos_system_state_get(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
|  ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns U32_t.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! U32_t !! Description&lt;br /&gt;
|-&lt;br /&gt;
| STATUS_INVALID || Failed to read System State Status&lt;br /&gt;
|-&lt;br /&gt;
| &amp;gt;= 0   || System State Status&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
 U32_t status;&lt;br /&gt;
 status = oceos_system_state_get();&lt;br /&gt;
 if (STATUS_INVALID == status) {&lt;br /&gt;
   // Handle ERROR&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_state_set()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''system_log.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Set system state variable and save previous setting to System State variable OLD. Setting to zero means resetting the System State status&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS   oceos_system_state_set(&lt;br /&gt;
    U32_t new_state              // new value of system state variable&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| new_state || New value of system state variable&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns enum DIRECTIVE_STATUS.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! enum DIRECTIVE_STATUS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| INCORRECT_STATE || System Meta pointer is NULL or Log pointer is NULL&lt;br /&gt;
|-&lt;br /&gt;
| SUCCESSFUL      || All OK&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS status;&lt;br /&gt;
U32_t sys_state = 0;&lt;br /&gt;
status = oceos_system_state_set(sys_state);&lt;br /&gt;
if (SUCCESSFUL != status) {&lt;br /&gt;
  // Handle ERROR&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_watchdog_init()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''FDIR.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''FOR GR716 ONLY'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This directive initializes the watchdog for GR716 at 0x80003070. The watchdog window reload value is in the control register. Large window sizes make resets more likely.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS   oceos_system_watchdog_init(&lt;br /&gt;
    BOOLE_t enable,            // enabled initially&lt;br /&gt;
    U32_t timeout,             // watchdog timeout&lt;br /&gt;
    U8_t window_size           // watchdog window&lt;br /&gt;
 );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| enable      || TRUE to enable watchdog at initialization&lt;br /&gt;
|-&lt;br /&gt;
| timeout     || Watchdog timeout&lt;br /&gt;
|-&lt;br /&gt;
| window_size || Watchdog windows size&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns enum DIRECTIVE_STATUS.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! enum DIRECTIVE_STATUS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| INVALID_NUMBER  || Parameter check failed&lt;br /&gt;
|-&lt;br /&gt;
| SUCCESSFUL      || All OK&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
 enum DIRECTIVE_STATUS status;&lt;br /&gt;
 status = oceos_system_watchdog_init(TRUE, 1000, 0xFF);&lt;br /&gt;
 if (SUCCESSFUL != status) {&lt;br /&gt;
   // Handle ERROR&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_watchdog_enable()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''FDIR.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''FOR GR716 ONLY'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This directive enables the watchdog for GR716 at 0x80003070 which will use timeout and window values setup previously.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS  oceos_system_watchdog_enable();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
|  ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns enum DIRECTIVE_STATUS.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! enum DIRECTIVE_STATUS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| SUCCESSFUL     || All OK&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS status;&lt;br /&gt;
status = oceos_system_watchdog_enable();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_watchdog_disable()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''FDIR.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''FOR GR716 ONLY'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This directive disables the watchdog for GR716 at 0x80003070.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS  oceos_system_watchdog_disable();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
|  ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns enum DIRECTIVE_STATUS.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! enum DIRECTIVE_STATUS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| SUCCESSFUL     || All OK&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS status;&lt;br /&gt;
status = oceos_system_watchdog_disable();    &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_watchdog_ticks_remaining()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''FDIR.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''FOR GR716 ONLY'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This directive returns number of ticks remaining in watchdog timer for GR716 at 0x80003070.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
unsigned int  oceos_system_watchdog_ticks_remaining();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
|  ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns unsigned int.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! unsigned int !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;gt;= 0 || Number of watchdog ticks &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
unsigned int num_ticks;&lt;br /&gt;
num_ticks = oceos_system_watchdog_ticks_remaining();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_watchdog_reset()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''FDIR.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''FOR GR716 ONLY'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This directive resets the watchdog timer for GR716 at 0x80003070, allowing it to be enabled or disabled after reset.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS  oceos_system_watchdog_reset(&lt;br /&gt;
    BOOLE_t enable     // whether to enable or disable after reset&lt;br /&gt;
 );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| enable || Whether to enable or disable after reset&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns enum DIRECTIVE_STATUS.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! enum DIRECTIVE_STATUS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| SUCCESSFUL     || All OK&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
 enum DIRECTIVE_STATUS status;&lt;br /&gt;
 status = oceos_system_watchdog_reset(TRUE);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_fdir&amp;diff=1486</id>
		<title>OCEOS/oceos fdir</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_fdir&amp;diff=1486"/>
		<updated>2022-04-08T10:03:16Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* FDIR Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS  Fault Detection, Isolation and Recovery (FDIR)'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
==&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;FDIR Introduction&amp;lt;/span&amp;gt;==&lt;br /&gt;
Hardware and software faults can occur that affect the behavior of the system. To detect such faults and anomalies, as scheduling proceeds OCEOS automatically checks that its key data areas have not been corrupted and that uses of resources are within their prescribed bounds. Parameters passed to directives are checked for consistency with the values originally declared in the application configuration.&amp;lt;br&amp;gt;&lt;br /&gt;
Once detected, OCEOS provides five levels of responses to faults and anomalies:&amp;lt;br&amp;gt;&lt;br /&gt;
'''Level 1''': The status code returned by a directive indicates that there was a problem&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The status code returned by a directive should always be checked.&amp;lt;br&amp;gt;&lt;br /&gt;
This code identifies whether the directive succeeded and if not indicates the reason for the failure.&amp;lt;br&amp;gt;&lt;br /&gt;
This is the only response made when the anomaly is an invalid parameter to a directive. It is combined with responses from other levels if a directive fails for some other reason.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
'''Level 2''': An appropriate log entry is added to the system log.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The log entry contains a code identifying the problem and a 32-bit timestamp.&amp;lt;br&amp;gt;&lt;br /&gt;
This response occurs in addition to the Level 1 response if a directive fails due to an internal factor such as the maximum number of jobs for a task being already created or a data queue being full.&amp;lt;br&amp;gt;&lt;br /&gt;
This response also occurs when a task misses its deadline or any unexpected behavior. This response is often accompanied by a Level 3 response.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
'''Level 3''': The system state variable is updated and a user defined problem handling function called.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The system state variable consists of 32 flags each indicating a particular problem type. It is reset by [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]]. A copy of this variable is also maintained. Both variables may be reset by the ASW.&lt;br /&gt;
This response occurs also in most circumstances where the Level 2 response occurs.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
'''Level 4''': An ASW problem handling function is called by OCEOS.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
A problem handling function can be identified in the application configuration structure passed to [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] and if present may be called by OCEOS.&lt;br /&gt;
This function can read the system log and system state variable, read the task timing and other information, enable and disable tasks, reset counting semaphores and data queues, and if necessary exit OCEOS. It can reset the system state variable, it is recommended that the copy of the system state variable not be reset so as to provide a longer term record of problems.&amp;lt;br&amp;gt;&lt;br /&gt;
This response occurs also in most circumstances where the Level 3 response occurs&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
'''Level 5''': OCEOS exits and returns to the ASW with an appropriate status code.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The status code in effect provides a Level 1 response to the [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] directive used by the ASW to start OCEOS. In normal circumstances OCEOS never returns to the ASW.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
This response by OCEOS only occurs when it detects that one of its essential internal elements has been corrupted. Depending on the severity of this corruption a Level 2 response may also be provided if possible, and the system state variable may also be updated. The user defined problem handling function is not called.&lt;br /&gt;
&lt;br /&gt;
If OCEOS exits the ASW can inspect the system log and system status variable, and also the task timings and other information maintained by OCEOS. The ASW can decide what corrective action should be taken and may resume scheduling with a call to [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The ASW can also inspect these items during scheduling, allowing it check the state of the system at any time.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This approach provides a graduated response by OCEOS to problems and allows some problems be isolated and recovered by, for example, disabling tasks or clearing a data queue if an appropriate problem handling function is provided as part of the ASW. The ASW may also check system information at any time to determine whether things are proceeding as expected.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
The ASW may set up a watchdog timer which will cause a system reset if a certain time elapses before it is reset. By using a lowest priority task to reset the watchdog failure of higher priority tasks to complete within their expected time can be detected. In OCEOS the lowest priority task, if it is the only task at that priority, is allowed to run forever and may be used to reset the watchdog. &amp;lt;br&amp;gt;&lt;br /&gt;
OCEOS provides watchdog timer functionality for GR716 target and not part of OCEOS for other targets.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
The log area contains the System State Variable, the system log, and the optional context switch log.&lt;br /&gt;
&lt;br /&gt;
The OCEOS system state variable contains flags that indicate a certain problem has occurred. It is automatically updated by OCEOS using ‘OR’ to avoiding losing information, typically a user defined function is called to deal with the problem.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Two sets of flags are kept as part of the system state variable. One accumulates indicators of all problems that have occurred, and typically is reset by the application only after a restart. The other indicates current problems, and typically is reset by the user defined problem handling function. For system state variable location please see [[OCEOS/oceos introduction#OCEOS_Data_Area_Layouts|HERE]].&amp;lt;br&amp;gt;&lt;br /&gt;
Application developer can provide system status mask that is used to AND with system status variable and if not zero, calls user defined error handling function. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *&lt;br /&gt;
 * SYSTEM STATUS VARIABLE FLAGS&lt;br /&gt;
 *&lt;br /&gt;
 * These are stored in the 32-bit system status variable &lt;br /&gt;
 * and updated by OCEOS when a problem is detected.&lt;br /&gt;
 * Resetting them is the responsibility of the application.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#define  STATUS_NORMAL                    0U    // no flag set&lt;br /&gt;
#define  STATUS_MASK_NORMAL      0x0U           // no error function can be called&lt;br /&gt;
#define  STATUS_INVALID          0xffffffffU    // system status invalid&lt;br /&gt;
&lt;br /&gt;
/* Task related problems */&lt;br /&gt;
#define  STATUS_DISABLED_TASK_START    0x1U    // An attempt to start a disabled task&lt;br /&gt;
#define  STATUS_TASK_JOB_LIMIT_OVER    0x2U    // An attempt to execute a task when its jobs limit is already reached.&lt;br /&gt;
#define  STATUS_JOB_OVER_TIME          0x4U    // Job time from creation to completion exceeds allowed maximum for task. YES&lt;br /&gt;
#define  STATUS_JOB_INTERVAL_SHORT     0x8U    // Minimum time between job creations is less than the allowed minimum for task&lt;br /&gt;
#define  STATUS_READYQ_FULL           0x10U    // Ready queue unable to accept job as result of being full&lt;br /&gt;
#define  STATUS_READYQ_NO_REMOVE      0x20U    // Remove job from ready queue failed&lt;br /&gt;
&lt;br /&gt;
/* Mutex related problems */&lt;br /&gt;
#define  STATUS_MUTEX_ALREADY_HELD    0x40U    // Mutex wait() when mutex already held&lt;br /&gt;
#define  STATUS_MUTEX_NOT_HELD        0x80U    // Mutex signal() when not already held&lt;br /&gt;
#define  STATUS_MUTEX_NOT_RETURNED   0x100U    // Mutex not returned before job terminates&lt;br /&gt;
#define  STATUS_MUTEX_NOT_NESTED     0x200U    // Use of multiple mutexes not nested&lt;br /&gt;
&lt;br /&gt;
/* Counting semaphore and data queue related problems */&lt;br /&gt;
#define  STATUS_SEMAPHORE_JOBS_FULL  0x400U    // Attempt to add job to semaphore pending list when list full&lt;br /&gt;
#define  STATUS_DATAQ_JOBS_FULL      0x800U    // Attempt to add job to data queue pending list when list full&lt;br /&gt;
#define  STATUS_DATAQ_FULL          0x1000U    // Data queue write when queue already full&lt;br /&gt;
&lt;br /&gt;
/* Timed actions related problems */&lt;br /&gt;
#define  STATUS_TIMED_JOBS_FULL     0x2000U    // Timed actions queue already full for timed task start&lt;br /&gt;
#define  STATUS_TIMED_OUTPUT_FULL   0x4000U    // Timed actions queue already full for timed output&lt;br /&gt;
#define  STATUS_TIMED_ACTION_LATE   0x8000U    // Timed action late                          YES&lt;br /&gt;
&lt;br /&gt;
/* Default trap handler should have been replaced&lt;br /&gt;
 * NOT USED AT THE MOMENT*/&lt;br /&gt;
#define  STATUS_SYSTEM_ERROR       0x10000U    // ERROR was handled by default trap handler  YES&lt;br /&gt;
&lt;br /&gt;
/* Flag to indicate problem with Stack Pointe&lt;br /&gt;
 * NOT USED AT THE MOMENT*/&lt;br /&gt;
#define  STATUS_SP_WARNING         0x20000U    // SP not in expected range&lt;br /&gt;
/* Log system error */&lt;br /&gt;
#define  STATUS_BAD_LOG            0x40000U    // System log problem&lt;br /&gt;
&lt;br /&gt;
/* Not using next few bits */&lt;br /&gt;
&lt;br /&gt;
/* Will have to exit */&lt;br /&gt;
#define  STATUS_BAD_SENTINEL     0x40000000U    // Area sentinel corrupt&lt;br /&gt;
#define  STATUS_BAD_META_PTR     0x80000000U    // Null meta pointer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;FDIR Configuration&amp;lt;/span&amp;gt;==&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
User can provide function, that is called in case of system ERROR&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  //  Application ERROR Handling code&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
/*&lt;br /&gt;
 * Create the application configuration structure&lt;br /&gt;
 */&lt;br /&gt;
struct application_configuration           app_config = {0};&lt;br /&gt;
app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;API Functions&amp;lt;/span&amp;gt;==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ API Functions&lt;br /&gt;
|-&lt;br /&gt;
! Directive                                                                                           !! Description                                 !! main !! task !! IRQ handler&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_state_get()|oceos_system_state_get()]]                              || Get the value of the system state variable  ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_state_set()|oceos_system_state_set()]]                              || Set system state variable                   ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_watchdog_init()|oceos_system_watchdog_init()]]                      || Initialize the watchdog                     ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_watchdog_enable()|oceos_system_watchdog_enable()]]                  || Enable the watchdog                         ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_watchdog_disable()|oceos_system_watchdog_disable()]]                || Disable the watchdog                        ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_watchdog_ticks_remaining()|oceos_system_watchdog_ticks_remaining()]]|| Get the number of ticks to watchdog timeout ||  *   ||  *   || *&lt;br /&gt;
|-&lt;br /&gt;
| [[OCEOS/oceos_fdir#oceos_system_watchdog_reset()|oceos_system_watchdog_reset()]]                    || Reset the watchdog                          ||  *   ||  *   || *&lt;br /&gt;
|}&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_state_get()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''system_log.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns the value of the system state variable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
U32_t                   oceos_system_state_get(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
|  ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns U32_t.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! U32_t !! Description&lt;br /&gt;
|-&lt;br /&gt;
| STATUS_INVALID || Failed to read System State Status&lt;br /&gt;
|-&lt;br /&gt;
| &amp;gt;= 0   || System State Status&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
 U32_t status;&lt;br /&gt;
 status = oceos_system_state_get();&lt;br /&gt;
 if (STATUS_INVALID == status) {&lt;br /&gt;
   // Handle ERROR&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_state_set()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''system_log.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Set system state variable and save previous setting to System State variable OLD. Setting to zero means resetting the System State status&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS   oceos_system_state_set(&lt;br /&gt;
    U32_t new_state              // new value of system state variable&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| new_state || New value of system state variable&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns enum DIRECTIVE_STATUS.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! enum DIRECTIVE_STATUS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| INCORRECT_STATE || System Meta pointer is NULL or Log pointer is NULL&lt;br /&gt;
|-&lt;br /&gt;
| SUCCESSFUL      || All OK&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS status;&lt;br /&gt;
U32_t sys_state = 0;&lt;br /&gt;
status = oceos_system_state_set(sys_state);&lt;br /&gt;
if (SUCCESSFUL != status) {&lt;br /&gt;
  // Handle ERROR&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_watchdog_init()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''FDIR.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''FOR GR716 ONLY'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This directive initializes the watchdog for GR716 at 0x80003070. The watchdog window reload value is in the control register. Large window sizes make resets more likely.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS   oceos_system_watchdog_init(&lt;br /&gt;
    BOOLE_t enable,            // enabled initially&lt;br /&gt;
    U32_t timeout,             // watchdog timeout&lt;br /&gt;
    U8_t window_size           // watchdog window&lt;br /&gt;
 );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| enable      || TRUE to enable watchdog at initialization&lt;br /&gt;
|-&lt;br /&gt;
| timeout     || Watchdog timeout&lt;br /&gt;
|-&lt;br /&gt;
| window_size || Watchdog windows size&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns enum DIRECTIVE_STATUS.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! enum DIRECTIVE_STATUS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| INVALID_NUMBER  || Parameter check failed&lt;br /&gt;
|-&lt;br /&gt;
| SUCCESSFUL      || All OK&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
 enum DIRECTIVE_STATUS status;&lt;br /&gt;
 status = oceos_system_watchdog_init(TRUE, 1000, 0xFF);&lt;br /&gt;
 if (SUCCESSFUL != status) {&lt;br /&gt;
   // Handle ERROR&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_watchdog_enable()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''FDIR.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''FOR GR716 ONLY'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This directive enables the watchdog for GR716 at 0x80003070 which will use timeout and window values setup previously.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS  oceos_system_watchdog_enable();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
|  ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns enum DIRECTIVE_STATUS.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! enum DIRECTIVE_STATUS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| SUCCESSFUL     || All OK&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS status;&lt;br /&gt;
status = oceos_system_watchdog_enable();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_watchdog_disable()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''FDIR.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''FOR GR716 ONLY'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This directive disables the watchdog for GR716 at 0x80003070.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS  oceos_system_watchdog_disable();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
|  ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns enum DIRECTIVE_STATUS.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! enum DIRECTIVE_STATUS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| SUCCESSFUL     || All OK&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS status;&lt;br /&gt;
status = oceos_system_watchdog_disable();    &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_watchdog_ticks_remaining()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''FDIR.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''FOR GR716 ONLY'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This directive returns number of ticks remaining in watchdog timer for GR716 at 0x80003070.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
unsigned int  oceos_system_watchdog_ticks_remaining();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
|  ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns unsigned int.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! unsigned int !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;gt;= 0 || Number of watchdog ticks &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
unsigned int num_ticks;&lt;br /&gt;
num_ticks = oceos_system_watchdog_ticks_remaining();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;oceos_system_watchdog_reset()&amp;lt;/span&amp;gt;===&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Header File'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''FDIR.h'''''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Description'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''FOR GR716 ONLY'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This directive resets the watchdog timer for GR716 at 0x80003070, allowing it to be enabled or disabled after reset.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Prototype'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
enum DIRECTIVE_STATUS  oceos_system_watchdog_reset(&lt;br /&gt;
    BOOLE_t enable     // whether to enable or disable after reset&lt;br /&gt;
 );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Parameters'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| enable || Whether to enable or disable after reset&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Returns'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This function returns enum DIRECTIVE_STATUS.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! enum DIRECTIVE_STATUS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| SUCCESSFUL     || All OK&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;'''Example Usage'''&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
 enum DIRECTIVE_STATUS status;&lt;br /&gt;
 status = oceos_system_watchdog_reset(TRUE);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1485</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1485"/>
		<updated>2022-04-04T13:45:42Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 '''Documentation'''/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 '''Examples'''/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 '''include'''/                             // OCEOS header files&lt;br /&gt;
 '''OCEOS_GCC_LIB'''/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Normal operations&amp;lt;/span&amp;gt;====&lt;br /&gt;
The scheduling is started after calling [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The main structure of application flow is described below:&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] - Initialize fixed data and start system time and log&lt;br /&gt;
# Create:&lt;br /&gt;
#* [[OCEOS/oceos kernel/task#oceos_task_create()|oceos_task_create()]] - Create task, setting priority, no of jobs, ..etc.&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/mutex#oceos_mutex_create()|oceos_mutex_create()]] - Create mutexes if require&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/dataq#oceos_dataq_create()|oceos_dataq_create()]] - Create data queues if require&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/semaphore#oceos_sem_create()|oceos_sem_create()]] - Create semaphores if require&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init_finish()|oceos_init_finish()]] - Initialize dynamic data area&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] - Start the scheduler and pass control to first task&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
It is mandatory to create the number of tasks, mutexes, semaphores, and data queues declared in oceos_config.h otherwise oceos_init_finish() will return an error.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OCEOS configuration parameters are shown below. In provided demo projects these are ''oceos_config.h'' and ''oceos_config.c''. More information can be found by clicking on the link for parameter that is of interest.&lt;br /&gt;
&lt;br /&gt;
 // ''1: Includes OCEOS main header file''&lt;br /&gt;
 #include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''2: Number of Log entries.''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|NUMBER_OF_LOG_ENTRIES]]                   16 // ''16 to 1024, default 64''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''3: Number of tasks''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_TASKS]]                         3  // 1 to 255&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);''&lt;br /&gt;
 //    ''Defaults to number of tasks, as each task should have aa least one job;''&lt;br /&gt;
 //    ''If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_READYQ_ENTRIES]]                10&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''5: Number of Mutexes''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/mutex#Mutex_Configuration|NUMBER_OF_MUTEXES]]                       2  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''6: Number of Semaphores''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/semaphore#Semaphore_Configuration|NUMBER_OF_SEMAPHORES]]                    0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''7: Number of Data Qs''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/dataq#Data_Queue_Configuration|NUMBER_OF_DATAQS]]                        0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''8: LOG data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|LOG_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''9: FIXED data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|FIXED_DATA_ARRAY_SIZE_U32S]]              0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''10: DYNAMIC data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|DYN_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''11: Timed Actions''&lt;br /&gt;
 #define [[OCEOS/oceos_timed_actions#Timed_Actions_Configuration|NUMBER_OF_ACTION_ENTRIES]]                0  // ''User-modify field''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''12: Log entries base 2''&lt;br /&gt;
 #define [[OCEOS/oceos_profiling#Configuration|CS_LOG_DEF_ENTRIES_BASE2]]                0&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''13: OCEOS stack start Address''&lt;br /&gt;
 #define OCEOS_STACK_START_ADDRESS               0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''14: OCEOS stack end address''&lt;br /&gt;
 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
&lt;br /&gt;
''application_init()'' function shown below creates OCEOS configuration struct and sets configuration parameter that passed to [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * Not Used for ARM. Always Nested&lt;br /&gt;
     */&lt;br /&gt;
    app_config.interrupt_nesting_enabled     = TRUE;                          // Nesting Enabled&lt;br /&gt;
#endif&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * ARM SysTick is used for System Time&lt;br /&gt;
     */&lt;br /&gt;
    app_config.sys_time_timer_index          = SYS_TIME_TIMER_INDEX;          // 0 =&amp;gt; invalid index&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    // System time is used by timed actions, semaphores with timeout, dataqs with timeout, logging and profiling.&lt;br /&gt;
    // If all of above are not required then system time can be disabled. The system will not be interrupted by SysTick while CPU in sleep mode,&lt;br /&gt;
    //but it is not the case for SPARC targets,&lt;br /&gt;
    // as system time implemented by chaining two timers without interrupting.&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all ARM_BUILD=1 FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 4 – Timer interrupt starts task&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- =&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
In common situation embedded application would call list of functions in a while loop and interrupt service routines are used for critical operations.&amp;lt;br&amp;gt;&lt;br /&gt;
Using RTOS for the same application would make developers life easier and would save power consumption. &lt;br /&gt;
Each function in a list of while loop can represent the task and started only when something really happen. Most of RTOS available today would use priority controlled round-robin scheduling. Where the tasks require different response time developer could assigned different priorities for those tasks and scheduling according to those priorities. Tasks with the same priorities are scheduled using round-robin.&lt;br /&gt;
&lt;br /&gt;
This is where OCEOS is different. &lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_inter-task_communication&amp;diff=1484</id>
		<title>OCEOS/oceos inter-task communication</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_inter-task_communication&amp;diff=1484"/>
		<updated>2022-04-01T12:56:08Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* Synchronization and Inter-task Communication */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Synchronization and Inter-task Communication'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
Many data structures cannot be fully accessed with a single instruction. Errors can result if a job using such a structure is pre-empted by another job that also uses the structure.&amp;lt;br&amp;gt;&lt;br /&gt;
To address this OCEOS provides up to 63 mutual exclusion semaphores [[OCEOS/oceos inter-task communication/mutex|mutexes]]. Each shared data structure or critical code segment typically is associated with its own mutex.&amp;lt;br&amp;gt;&lt;br /&gt;
Any job that uses a shared item should first acquire its mutex from OCEOS, and when finished with the item return the mutex. The number of instructions for which the mutex is held must be finite.&amp;lt;br&amp;gt;&lt;br /&gt;
OCEOS allows a mutex be held by only one job at any one time. A job that uses a shared data structure or critical code segment can use an associated mutex to exclude all other jobs.&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
An OS does not prevent a shared resource being accessed if no attempt is made to acquire its mutex. The software developer must ensure this is done before the shared resource is used.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OCEOS provides two types of inter-job communication, counting semaphores and data queues. Semaphores and data queues are handled by OCEOS in a way different to many other OS.&amp;lt;br&amp;gt;&lt;br /&gt;
In most OS a job that waits on a zero semaphore or tries to read an empty data queue may be blocked at that point and wait there indefinitely or with an optional timeout.&amp;lt;br&amp;gt;&lt;br /&gt;
In OCEOS an active job may be pre-empted but cannot otherwise be blocked, so three options are provided in case a counting semaphore is zero when waited on or a data queue is empty when read:&amp;lt;br&amp;gt;&lt;br /&gt;
# One option results in a value always being returned and the job continuing. The returned value will indicate that the semaphore was zero or queue empty, and the job can take this into account.&lt;br /&gt;
# In the other options, if the semaphore is zero or queue empty the job terminates and will restart from its beginning when the semaphore is signalled or queue written, or after an optional timeout.&lt;br /&gt;
# When the job becomes active again after a timeout and again encounters the second option the behavior is as with the first option, the job continues and takes into account that a timeout has occurred.&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
Because a job restarts when a resource becomes available rather than waiting at the point where it sought the resource any local data developed up to that point will be lost unless stored non-locally for use after the restart. &amp;lt;br&amp;gt;&lt;br /&gt;
If required this can be done using static variables or structures, or using data queues or counting semaphores.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
'''In OCEOS event communication between tasks or between tasks and interrupt handlers is done typically by using counting semaphores.'''&lt;br /&gt;
&lt;br /&gt;
*[[OCEOS/oceos_inter-task_communication/mutex| OCEOS Mutexes]]&lt;br /&gt;
*[[OCEOS/oceos_inter-task_communication/dataq| OCEOS Data Queues]]&lt;br /&gt;
*[[OCEOS/oceos_inter-task_communication/semaphore| OCEOS Counting Semaphores]]&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_profiling&amp;diff=1482</id>
		<title>OCEOS/oceos profiling</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_profiling&amp;diff=1482"/>
		<updated>2022-03-31T16:57:24Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Profiling'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
==&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Introduction&amp;lt;/span&amp;gt;==&lt;br /&gt;
Each time a context switch or interrupt occurs, four 32-bit words are added to the context switch log if enabled:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. The first of these describes the type of switch and also gives the current window pointer (CWP) and the low 8 bits of the high 32 bits of the 64-bit system time when the switch occurred.&lt;br /&gt;
 Switch information:&lt;br /&gt;
 8 bits high time bits (31 to 24)&lt;br /&gt;
 5 bits CWP (23 to 19)&lt;br /&gt;
 1 bit (18) switch type, 0=&amp;gt; starting, 1 =&amp;gt; interrupt or ending&lt;br /&gt;
 1 bit (17) ‘from’ ID type, 0=&amp;gt; from task, 1 =&amp;gt; from interrupt&lt;br /&gt;
 1 bit (16) ‘to’ ID type, 0 =&amp;gt; to task, 1 =&amp;gt; to interrupt&lt;br /&gt;
 8 bits (15 to 8) ID of task/interrupt from which switching&lt;br /&gt;
 8 bits (7 to 0) ID of task/interrupt to which switching&lt;br /&gt;
&lt;br /&gt;
 TASK_ID_INVALID (0xff) is used to indicate switching to or from the scheduler itself. The interrupt ID 0 is not expected to occur, used as TO when CPU put to sleep Initialized by oceos_start() to 0x0000ffff (invalid as scheduler doesn’t switch to itself).&lt;br /&gt;
2. The second gives the 32-bit system time in microseconds at which the switch occurred.&lt;br /&gt;
 Context switch time word&lt;br /&gt;
3. The third gives the start delay if a task is being started, otherwise a signed int giving the remaining time until the deadline or INT_MAX if the task has no deadline, a negative value gives by how much the deadline has been missed. &lt;br /&gt;
 Low 32 bits of the time at which switch happened. The next 8 bits of the 64-bit system time are given in the switch information word, giving an overall 40-bit time value. Initialized to 0.&lt;br /&gt;
 Start wait time / deadline time margin word.&lt;br /&gt;
 When first starting a task, the delay between the start request and execution beginning. Otherwise a signed int giving remaining time until deadline or 0x7fffffff if no deadline. Initialized to 0.&lt;br /&gt;
4. The fourth gives the current system stack pointer.&lt;br /&gt;
 System stack pointer when switch was made. Initialized to 0.&lt;br /&gt;
The user specifies the number of entries in the context switch log in the application configuration. This size is given as a number in the range 3 to 12, resulting in from 2^3 to 2^12 entries. If a size outside this range is specified no context switch log is present (no header and no entries).&lt;br /&gt;
&lt;br /&gt;
If valid, the size is stored in sysMetaPtr-&amp;gt;CS_log_entries_base2. If invalid this holds 0, CS logging is off.&lt;br /&gt;
&lt;br /&gt;
Stored in log area immediately after last system log entry and before END_SENTINEL for log area.&lt;br /&gt;
&lt;br /&gt;
Space needed for CS log is included in log area size recorded at the start of the log area.&lt;br /&gt;
&lt;br /&gt;
Number of CS log entries is 2^size unless size is invalid, in which case no storage is used.&lt;br /&gt;
&lt;br /&gt;
If sysMetaPtr-&amp;gt;CS_log_entries_base2 is outside the allowed range (typically 0) no context switch logging is done. The CS header is not present, END_SENTINEL is at that position instead.&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Configuration&amp;lt;/span&amp;gt;==&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
User must define CS_LOG_DEF_ENTRIES_BASE2 and value 0 if Context switch logging is disabled or in the range 3 to 12 if context switch has to be enabled.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    #define CS_LOG_DEF_ENTRIES_BASE2  3&lt;br /&gt;
...&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
User must add extra space to log data area to accommodate context switch logging. Please read more [[OCEOS/oceos_logging#Logging_Configuration|HERE]].&lt;br /&gt;
Defined parameter LOG_DATA_ARRAY_SIZE_U32S must be big enough to hold context switch logging data.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x100 // Log Area plus Context switch Area, if context switch is enabled&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
...&lt;br /&gt;
/*&lt;br /&gt;
 * Create the application configuration structure&lt;br /&gt;
 */&lt;br /&gt;
struct application_configuration           app_config = {0};&lt;br /&gt;
app_config.log_address                   = (adrs_t)log_data;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
===== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;ARM Context Logging Configuration&amp;lt;/span&amp;gt; =====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
For ARM Cortex-M microcontrollers user must include in each implemented IRQ Handler at the start and at the end of the handler OCEOS code to do Context switch logging. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
Should be removed in production&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
This adds the information to the Context Switch Logging when IRQ was triggered. If user does not require some IRQs reflected in Context Switch Logging, this can be omitted.&amp;lt;br&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
OCEOS code is defined in ''oceos_arm_trap_handler.h'' header file that user must include.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#incude oceos_arm_trap_handler.h&lt;br /&gt;
&lt;br /&gt;
void user_device_irq_handler() {&lt;br /&gt;
  OCEOS_ISR_CS_LOG_START&lt;br /&gt;
&lt;br /&gt;
  // User Code to handle IRQ&lt;br /&gt;
&lt;br /&gt;
  OCEOS_ISR_CS_LOG_END&lt;br /&gt;
} // End&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;DMON Commands&amp;lt;/span&amp;gt;==&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;oceos profile &amp;lt;status|enable|disable&amp;gt;&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
:'''oceos profile''' displays context switch logging information. This functionality can be enabled/disabled or show current status of the command. Context switch logging should be enabled in OCEOS before this command can be used. More information about context switch logging can be found [[OCEOS/oceos_profiling#Introduction|'''here''']]. &lt;br /&gt;
&lt;br /&gt;
This command can be used only when DMON starts with -gui switch and executable with OCEOS loaded to the target. This view can be displayed in separate window.&lt;br /&gt;
&lt;br /&gt;
[[File:cpu_profile_main.png|600px|CPU Profile View]]&lt;br /&gt;
[[Media:cpu_profile_main.png|ZOOM]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The table below shows all the entries read from the target (system log messages, user log messages, context switching from context to context). DMON reads log area and context switch log area and presents in readable form. Available  information for each log entry depends on log type. Log types:&lt;br /&gt;
&lt;br /&gt;
*System log entry&lt;br /&gt;
:Displays log error type and extra log information&lt;br /&gt;
*User log entry&lt;br /&gt;
:Displays user defined value and extra log information&lt;br /&gt;
*Switch from task to task&lt;br /&gt;
**Starting new task&lt;br /&gt;
*:Displays delay between request to start the task and actual time when task was started&lt;br /&gt;
**Ending task&lt;br /&gt;
:Displays remaining time until deadline if was specified by user, when task was created&lt;br /&gt;
*Switch from task to scheduler&lt;br /&gt;
*Switch from task to sleep&lt;br /&gt;
&lt;br /&gt;
:Also DMON displays stack pointer at the time of context switch, CWP(current window pointer) and system state variable.&lt;br /&gt;
&lt;br /&gt;
The table allows browsing through the list of log entries, moving from one context to another. Double click on any entry in the table sets the marker on the time line. Zoom in and out can be used only then to have a closer look at selected time frame. Time Line and Stack view are synchronized to match the currently selected entry.&lt;br /&gt;
&lt;br /&gt;
[[File:cpu_profile_table.png|600px|Table view]]&lt;br /&gt;
[[Media:cpu_profile_table.png|ZOOM]]&lt;br /&gt;
&lt;br /&gt;
The Stack Graph below displays stack for the last minute. Stack displays between MIN and MAX values if specified by user in app_config.c&lt;br /&gt;
&lt;br /&gt;
[[File:cpu_profile_stack.png|600px|Stack view]]&lt;br /&gt;
[[Media:cpu_profile_stack.png|ZOOM]]&lt;br /&gt;
&lt;br /&gt;
The Time Line view below displays system interaction by context over time. Each row presents the context. Tasks are ordered by its priorities, from higher to lower. The first row presents the overall context switch activities. The real time update of Time Line is possible only at 10ms scale by moving the scroll bar to the max on the right. &lt;br /&gt;
&lt;br /&gt;
Task run time is shown as rectangle filled with task specific color.&lt;br /&gt;
&lt;br /&gt;
Context switches marked with vertical lines.&lt;br /&gt;
&lt;br /&gt;
Grey rectangle before task indicates the time from start request to actual task start. &lt;br /&gt;
&lt;br /&gt;
DMON can detect buffer overrun. The message is printed to the console and red vertical line displayed on the Time Line View. If this happened, context switch log buffer size has to be increased.  &lt;br /&gt;
&lt;br /&gt;
[[File:cpu_profile_timeline.png|600px|Time Line view]]&lt;br /&gt;
[[Media:cpu_profile_timeline.png|ZOOM]]&lt;br /&gt;
&lt;br /&gt;
Setting the marker by double clicking on the entry in the table&lt;br /&gt;
&lt;br /&gt;
[[File:cpu_profile_10ms.png|600px|Time Line view at 10ms]]&lt;br /&gt;
[[Media:cpu_profile_10ms.png|ZOOM]]&lt;br /&gt;
&lt;br /&gt;
Zoom in to 1 micro second&lt;br /&gt;
&lt;br /&gt;
[[File:cpu_profile_1.png|600px|Time Line view at 1 micro second]]&lt;br /&gt;
[[Media:cpu_profile_1.png|ZOOM]]&lt;br /&gt;
&lt;br /&gt;
Time Line view has some basic controls:&lt;br /&gt;
*Status (running/paused)&lt;br /&gt;
*Button to enable/disable command&lt;br /&gt;
*Save button (please see below)&lt;br /&gt;
*Slider to change time scale. It is disabled and defaults to 10ms while updating in real time.&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
'''Limitations:'''&lt;br /&gt;
If Context switch buffer is too big it puts constrains on the link to the target. This can happen if the rate, at which the tasks are started, is very frequent. If this is the case then this feature cannot be used and [[OCEOS/oceos debugging#oceos_cpuload_.3Cstatus.7Cenable.7Cdisable.3E|oceos cpuload]] command is the only choice, as it does not depend on buffer size.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color:#1b7ac2&amp;quot;&amp;gt;oceos profile save &amp;lt;fileName&amp;gt; &amp;lt;/span&amp;gt;===&lt;br /&gt;
:'''oceos profile save''' saves context switch logging to the csv file. This command activates saving to the file. After all content is saved, it continues appending to the file. This command cannot be disabled. Every time when new image is loaded to the target, new csv file is created. &lt;br /&gt;
&lt;br /&gt;
If fileName parameter is not specified, the file is created in DMON User directory: c:\Users\UserName\DMON\UserData&lt;br /&gt;
&lt;br /&gt;
 [[File:Cpu_profile_save.png|Sample of saved Context switch logging to csv file]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=MediaWiki:Sidebar&amp;diff=1481</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=MediaWiki:Sidebar&amp;diff=1481"/>
		<updated>2022-03-31T16:51:35Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** Main Page|OCE wiki&lt;br /&gt;
*  DMON&lt;br /&gt;
** DMON install &amp;amp; use|DMON install &amp;amp; use&lt;br /&gt;
** DMON facilities|DMON facilities&lt;br /&gt;
** DMON commands|DMON commands&lt;br /&gt;
** DMON SOC support|DMON SOC support&lt;br /&gt;
** DMON Eclipse debug|DMON Eclipse debug&lt;br /&gt;
** DMON OCEOS Support|DMON OCEOS Support&lt;br /&gt;
** DMON Troubleshooting|DMON Troubleshooting&lt;br /&gt;
* OCEOS&lt;br /&gt;
** OCEOS/oceos_introduction|Introduction&lt;br /&gt;
** OCEOS/oceos_kernel|Kernel&lt;br /&gt;
** OCEOS/oceos_inter-task_communication|Inter-task Communication&lt;br /&gt;
** OCEOS/oceos_timed_actions|Timed Actions&lt;br /&gt;
** OCEOS/oceos_logging|Logging&lt;br /&gt;
** OCEOS/oceos_fdir|FDIR&lt;br /&gt;
** OCEOS/oceos_protection|Protection (GR716)&lt;br /&gt;
** OCEOS/oceos_debugging|Debugging&lt;br /&gt;
** OCEOS/oceos_profiling|Profiling&lt;br /&gt;
** OCEOS/oceos_use|Installation&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=MediaWiki:Sidebar&amp;diff=1480</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=MediaWiki:Sidebar&amp;diff=1480"/>
		<updated>2022-03-31T16:50:29Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** Main Page|OCE wiki&lt;br /&gt;
*  DMON&lt;br /&gt;
** DMON install &amp;amp; use|DMON install &amp;amp; use&lt;br /&gt;
** DMON facilities|DMON facilities&lt;br /&gt;
** DMON commands|DMON commands&lt;br /&gt;
** DMON SOC support|DMON SOC support&lt;br /&gt;
** DMON Eclipse debug|DMON Eclipse debug&lt;br /&gt;
** DMON OCEOS Support|DMON OCEOS Support&lt;br /&gt;
** DMON Troubleshooting|DMON Troubleshooting&lt;br /&gt;
*  [[OCEOS|OCEOS]]&lt;br /&gt;
** OCEOS/oceos_introduction|Introduction&lt;br /&gt;
** OCEOS/oceos_kernel|Kernel&lt;br /&gt;
** OCEOS/oceos_inter-task_communication|Inter-task Communication&lt;br /&gt;
** OCEOS/oceos_timed_actions|Timed Actions&lt;br /&gt;
** OCEOS/oceos_logging|Logging&lt;br /&gt;
** OCEOS/oceos_fdir|FDIR&lt;br /&gt;
** OCEOS/oceos_protection|Protection (GR716)&lt;br /&gt;
** OCEOS/oceos_debugging|Debugging&lt;br /&gt;
** OCEOS/oceos_profiling|Profiling&lt;br /&gt;
** OCEOS/oceos_use|Installation&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=MediaWiki:Sidebar&amp;diff=1479</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=MediaWiki:Sidebar&amp;diff=1479"/>
		<updated>2022-03-31T16:49:10Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** Main Page|OCE wiki&lt;br /&gt;
*  &lt;br /&gt;
** DMON install &amp;amp; use|DMON install &amp;amp; use&lt;br /&gt;
** DMON facilities|DMON facilities&lt;br /&gt;
** DMON commands|DMON commands&lt;br /&gt;
** DMON SOC support|DMON SOC support&lt;br /&gt;
** DMON Eclipse debug|DMON Eclipse debug&lt;br /&gt;
** DMON OCEOS Support|DMON OCEOS Support&lt;br /&gt;
** DMON Troubleshooting|DMON Troubleshooting&lt;br /&gt;
*  &lt;br /&gt;
** OCEOS|OCEOS&lt;br /&gt;
** OCEOS/oceos_introduction|Introduction&lt;br /&gt;
** OCEOS/oceos_kernel|Kernel&lt;br /&gt;
** OCEOS/oceos_inter-task_communication|Inter-task Communication&lt;br /&gt;
** OCEOS/oceos_timed_actions|Timed Actions&lt;br /&gt;
** OCEOS/oceos_logging|Logging&lt;br /&gt;
** OCEOS/oceos_fdir|FDIR&lt;br /&gt;
** OCEOS/oceos_protection|Protection (GR716)&lt;br /&gt;
** OCEOS/oceos_debugging|Debugging&lt;br /&gt;
** OCEOS/oceos_profiling|Profiling&lt;br /&gt;
** OCEOS/oceos_use|Installation&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=MediaWiki:Sidebar&amp;diff=1478</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=MediaWiki:Sidebar&amp;diff=1478"/>
		<updated>2022-03-31T16:48:38Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** Main Page|OCE wiki&lt;br /&gt;
* DMON&lt;br /&gt;
** DMON install &amp;amp; use|DMON install &amp;amp; use&lt;br /&gt;
** DMON facilities|DMON facilities&lt;br /&gt;
** DMON commands|DMON commands&lt;br /&gt;
** DMON SOC support|DMON SOC support&lt;br /&gt;
** DMON Eclipse debug|DMON Eclipse debug&lt;br /&gt;
** DMON OCEOS Support|DMON OCEOS Support&lt;br /&gt;
** DMON Troubleshooting|DMON Troubleshooting&lt;br /&gt;
* OCEOS|OCEOS&lt;br /&gt;
** OCEOS|OCEOS&lt;br /&gt;
** OCEOS/oceos_introduction|Introduction&lt;br /&gt;
** OCEOS/oceos_kernel|Kernel&lt;br /&gt;
** OCEOS/oceos_inter-task_communication|Inter-task Communication&lt;br /&gt;
** OCEOS/oceos_timed_actions|Timed Actions&lt;br /&gt;
** OCEOS/oceos_logging|Logging&lt;br /&gt;
** OCEOS/oceos_fdir|FDIR&lt;br /&gt;
** OCEOS/oceos_protection|Protection (GR716)&lt;br /&gt;
** OCEOS/oceos_debugging|Debugging&lt;br /&gt;
** OCEOS/oceos_profiling|Profiling&lt;br /&gt;
** OCEOS/oceos_use|Installation&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=MediaWiki:Sidebar&amp;diff=1477</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=MediaWiki:Sidebar&amp;diff=1477"/>
		<updated>2022-03-31T16:48:14Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** Main Page|OCE wiki&lt;br /&gt;
* DMON&lt;br /&gt;
** DMON install &amp;amp; use|DMON install &amp;amp; use&lt;br /&gt;
** DMON facilities|DMON facilities&lt;br /&gt;
** DMON commands|DMON commands&lt;br /&gt;
** DMON SOC support|DMON SOC support&lt;br /&gt;
** DMON Eclipse debug|DMON Eclipse debug&lt;br /&gt;
** DMON OCEOS Support|DMON OCEOS Support&lt;br /&gt;
** DMON Troubleshooting|DMON Troubleshooting&lt;br /&gt;
* OCEOS/|OCEOS&lt;br /&gt;
** OCEOS/oceos_introduction|Introduction&lt;br /&gt;
** OCEOS/oceos_kernel|Kernel&lt;br /&gt;
** OCEOS/oceos_inter-task_communication|Inter-task Communication&lt;br /&gt;
** OCEOS/oceos_timed_actions|Timed Actions&lt;br /&gt;
** OCEOS/oceos_logging|Logging&lt;br /&gt;
** OCEOS/oceos_fdir|FDIR&lt;br /&gt;
** OCEOS/oceos_protection|Protection (GR716)&lt;br /&gt;
** OCEOS/oceos_debugging|Debugging&lt;br /&gt;
** OCEOS/oceos_profiling|Profiling&lt;br /&gt;
** OCEOS/oceos_use|Installation&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=MediaWiki:Sidebar&amp;diff=1476</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=MediaWiki:Sidebar&amp;diff=1476"/>
		<updated>2022-03-31T16:47:12Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** Main Page|OCE wiki&lt;br /&gt;
* DMON&lt;br /&gt;
** DMON install &amp;amp; use|DMON install &amp;amp; use&lt;br /&gt;
** DMON facilities|DMON facilities&lt;br /&gt;
** DMON commands|DMON commands&lt;br /&gt;
** DMON SOC support|DMON SOC support&lt;br /&gt;
** DMON Eclipse debug|DMON Eclipse debug&lt;br /&gt;
** DMON OCEOS Support|DMON OCEOS Support&lt;br /&gt;
** DMON Troubleshooting|DMON Troubleshooting&lt;br /&gt;
* OCEOS|OCEOS&lt;br /&gt;
** OCEOS/oceos_introduction|Introduction&lt;br /&gt;
** OCEOS/oceos_kernel|Kernel&lt;br /&gt;
** OCEOS/oceos_inter-task_communication|Inter-task Communication&lt;br /&gt;
** OCEOS/oceos_timed_actions|Timed Actions&lt;br /&gt;
** OCEOS/oceos_logging|Logging&lt;br /&gt;
** OCEOS/oceos_fdir|FDIR&lt;br /&gt;
** OCEOS/oceos_protection|Protection (GR716)&lt;br /&gt;
** OCEOS/oceos_debugging|Debugging&lt;br /&gt;
** OCEOS/oceos_profiling|Profiling&lt;br /&gt;
** OCEOS/oceos_use|Installation&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS&amp;diff=1475</id>
		<title>OCEOS</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS&amp;diff=1475"/>
		<updated>2022-03-31T16:44:17Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Contents&lt;br /&gt;
&lt;br /&gt;
 1.  [[OCEOS/oceos_introduction|OCEOS Introduction and Main Concepts]]&lt;br /&gt;
 2.  [[OCEOS/oceos_kernel|OCEOS Kernel]]&lt;br /&gt;
 3.  [[OCEOS/oceos_inter-task_communication|OCEOS Synchronization and Inter-task Communication]]&lt;br /&gt;
 4.  [[OCEOS/oceos_timed_actions|OCEOS Timed Actions (Software Timers)]]&lt;br /&gt;
 5.  [[OCEOS/oceos_logging|OCEOS Logging]]&lt;br /&gt;
 6.  [[OCEOS/oceos_fdir|OCEOS FDIR]]&lt;br /&gt;
 7.  [[OCEOS/oceos_protection|OCEOS Protection (GR716)]]&lt;br /&gt;
 8.  [[OCEOS/oceos_debugging|OCEOS Debugging]]&lt;br /&gt;
 9.  [[OCEOS/oceos_profiling|OCEOS Profiling]]&lt;br /&gt;
 10. [[OCEOS/oceos_use|OCEOS Installation and Use]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- OLD Menu  MediaWiki:Sidebar&lt;br /&gt;
** OCEOS_introduction|OCEOS Introduction&lt;br /&gt;
** OCEOS_Operation|OCEOS Operation&lt;br /&gt;
** OCEOS_Directives_Reference|OCEOS Directives&lt;br /&gt;
** OCEOS_Tutorials|OCEOS Tutorials&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS&amp;diff=1474</id>
		<title>OCEOS</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS&amp;diff=1474"/>
		<updated>2022-03-31T16:43:58Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Contents&lt;br /&gt;
&lt;br /&gt;
 1.  [[OCEOS/oceos_introduction|OCEOS Introduction and Main Concepts]]&lt;br /&gt;
 2.  [[OCEOS/oceos_kernel|OCEOS Kernel]]&lt;br /&gt;
 3.  [[OCEOS/oceos_inter-task_communication|OCEOS Synchronization and Inter-task Communication]]&lt;br /&gt;
 4.  [[OCEOS/oceos_timed_actions|OCEOS Timed Actions (Software Timers)]]&lt;br /&gt;
 5.  [[OCEOS/oceos_logging|OCEOS Logging]]&lt;br /&gt;
 6.  [[OCEOS/oceos_fdir|OCEOS FDIR]]&lt;br /&gt;
 7.  [[OCEOS/oceos_protection|OCEOS Protection (GR716)]]&lt;br /&gt;
 8.  [[OCEOS/oceos_debugging|OCEOS Debugging]]&lt;br /&gt;
 9.  [[OCEOS/oceos_profiling|OCEOS Profiling]]&lt;br /&gt;
 10. [[OCEOS/oceos_use|OCEOS Installation and Use]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- OLD Menu &lt;br /&gt;
** OCEOS_introduction|OCEOS Introduction&lt;br /&gt;
** OCEOS_Operation|OCEOS Operation&lt;br /&gt;
** OCEOS_Directives_Reference|OCEOS Directives&lt;br /&gt;
** OCEOS_Tutorials|OCEOS Tutorials&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=MediaWiki:Sidebar&amp;diff=1473</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=MediaWiki:Sidebar&amp;diff=1473"/>
		<updated>2022-03-31T16:42:25Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** Main Page|OCE wiki&lt;br /&gt;
* DMON&lt;br /&gt;
** DMON install &amp;amp; use|DMON install &amp;amp; use&lt;br /&gt;
** DMON facilities|DMON facilities&lt;br /&gt;
** DMON commands|DMON commands&lt;br /&gt;
** DMON SOC support|DMON SOC support&lt;br /&gt;
** DMON Eclipse debug|DMON Eclipse debug&lt;br /&gt;
** DMON OCEOS Support|DMON OCEOS Support&lt;br /&gt;
** DMON Troubleshooting|DMON Troubleshooting&lt;br /&gt;
* OCEOS&lt;br /&gt;
** OCEOS/oceos_introduction|Introduction&lt;br /&gt;
** OCEOS/oceos_kernel|Kernel&lt;br /&gt;
** OCEOS/oceos_inter-task_communication|Inter-task Communication&lt;br /&gt;
** OCEOS/oceos_timed_actions|Timed Actions&lt;br /&gt;
** OCEOS/oceos_logging|Logging&lt;br /&gt;
** OCEOS/oceos_fdir|FDIR&lt;br /&gt;
** OCEOS/oceos_protection|Protection (GR716)&lt;br /&gt;
** OCEOS/oceos_debugging|Debugging&lt;br /&gt;
** OCEOS/oceos_profiling|Profiling&lt;br /&gt;
** OCEOS/oceos_use|Installation&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=MediaWiki:Sidebar&amp;diff=1472</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=MediaWiki:Sidebar&amp;diff=1472"/>
		<updated>2022-03-31T16:41:31Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** Main Page|OCE wiki&lt;br /&gt;
* DMON&lt;br /&gt;
** DMON install &amp;amp; use|DMON install &amp;amp; use&lt;br /&gt;
** DMON facilities|DMON facilities&lt;br /&gt;
** DMON commands|DMON commands&lt;br /&gt;
** DMON SOC support|DMON SOC support&lt;br /&gt;
** DMON Eclipse debug|DMON Eclipse debug&lt;br /&gt;
** DMON OCEOS Support|DMON OCEOS Support&lt;br /&gt;
** DMON Troubleshooting|DMON Troubleshooting&lt;br /&gt;
* OCEOS&lt;br /&gt;
** OCEOS/oceos_introduction|OCEOS Introduction&lt;br /&gt;
** OCEOS/oceos_kernel|OCEOS Kernel&lt;br /&gt;
** OCEOS/oceos_inter-task_communication|OCEOS Inter-task Communication&lt;br /&gt;
** OCEOS/oceos_timed_actions|Timed Actions&lt;br /&gt;
** OCEOS/oceos_logging|OCEOS Logging&lt;br /&gt;
** OCEOS/oceos_fdir|OCEOS FDIR&lt;br /&gt;
** OCEOS/oceos_protection|OCEOS Protection (GR716)&lt;br /&gt;
** OCEOS/oceos_debugging|OCEOS Debugging&lt;br /&gt;
** OCEOS/oceos_profiling|OCEOS Profiling&lt;br /&gt;
** OCEOS/oceos_use|OCEOS Installation&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=MediaWiki:Sidebar&amp;diff=1471</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=MediaWiki:Sidebar&amp;diff=1471"/>
		<updated>2022-03-31T16:40:03Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** Main Page|OCE wiki&lt;br /&gt;
* DMON&lt;br /&gt;
** DMON install &amp;amp; use|DMON install &amp;amp; use&lt;br /&gt;
** DMON facilities|DMON facilities&lt;br /&gt;
** DMON commands|DMON commands&lt;br /&gt;
** DMON SOC support|DMON SOC support&lt;br /&gt;
** DMON Eclipse debug|DMON Eclipse debug&lt;br /&gt;
** DMON OCEOS Support|DMON OCEOS Support&lt;br /&gt;
** DMON Troubleshooting|DMON Troubleshooting&lt;br /&gt;
* OCEOS&lt;br /&gt;
&amp;lt;comment&amp;gt;&lt;br /&gt;
** OCEOS_introduction|OCEOS Introduction&lt;br /&gt;
** OCEOS_Operation|OCEOS Operation&lt;br /&gt;
** OCEOS_Directives_Reference|OCEOS Directives&lt;br /&gt;
** OCEOS_Tutorials|OCEOS Tutorials&lt;br /&gt;
&amp;lt;/comment&amp;gt;&lt;br /&gt;
** OCEOS/oceos_introduction|OCEOS Introduction and Main Concepts&lt;br /&gt;
** OCEOS/oceos_kernel|OCEOS Kernel&lt;br /&gt;
** OCEOS/oceos_inter-task_communication|OCEOS Synchronization and Inter-task Communication&lt;br /&gt;
** OCEOS/oceos_timed_actions|OCEOS Timed Actions (Software Timers)&lt;br /&gt;
** OCEOS/oceos_logging|OCEOS Logging&lt;br /&gt;
** OCEOS/oceos_fdir|OCEOS FDIR&lt;br /&gt;
** OCEOS/oceos_protection|OCEOS Protection (GR716)&lt;br /&gt;
** OCEOS/oceos_debugging|OCEOS Debugging&lt;br /&gt;
** OCEOS/oceos_profiling|OCEOS Profiling&lt;br /&gt;
** OCEOS/oceos_use|OCEOS Installation and Use&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=MediaWiki:Sidebar&amp;diff=1470</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=MediaWiki:Sidebar&amp;diff=1470"/>
		<updated>2022-03-31T16:39:19Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** Main Page|OCE wiki&lt;br /&gt;
* DMON&lt;br /&gt;
** DMON install &amp;amp; use|DMON install &amp;amp; use&lt;br /&gt;
** DMON facilities|DMON facilities&lt;br /&gt;
** DMON commands|DMON commands&lt;br /&gt;
** DMON SOC support|DMON SOC support&lt;br /&gt;
** DMON Eclipse debug|DMON Eclipse debug&lt;br /&gt;
** DMON OCEOS Support|DMON OCEOS Support&lt;br /&gt;
** DMON Troubleshooting|DMON Troubleshooting&lt;br /&gt;
* OCEOS&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
** OCEOS_introduction|OCEOS Introduction&lt;br /&gt;
** OCEOS_Operation|OCEOS Operation&lt;br /&gt;
** OCEOS_Directives_Reference|OCEOS Directives&lt;br /&gt;
** OCEOS_Tutorials|OCEOS Tutorials&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
** OCEOS/oceos_introduction|OCEOS Introduction and Main Concepts&lt;br /&gt;
** OCEOS/oceos_kernel|OCEOS Kernel&lt;br /&gt;
** OCEOS/oceos_inter-task_communication|OCEOS Synchronization and Inter-task Communication&lt;br /&gt;
** OCEOS/oceos_timed_actions|OCEOS Timed Actions (Software Timers)&lt;br /&gt;
** OCEOS/oceos_logging|OCEOS Logging&lt;br /&gt;
** OCEOS/oceos_fdir|OCEOS FDIR&lt;br /&gt;
** OCEOS/oceos_protection|OCEOS Protection (GR716)&lt;br /&gt;
** OCEOS/oceos_debugging|OCEOS Debugging&lt;br /&gt;
** OCEOS/oceos_profiling|OCEOS Profiling&lt;br /&gt;
** OCEOS/oceos_use|OCEOS Installation and Use&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_introduction&amp;diff=1469</id>
		<title>OCEOS/oceos introduction</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_introduction&amp;diff=1469"/>
		<updated>2022-03-31T16:33:48Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* OCEOS Memory Requirements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt; =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
OCEOS is a pre-emptive real time operating system (RTOS) with a small memory footprint intended for hard real time systems that use the '''GR716 micro-controller, SPARC LEON2/3/4 processors and ARM Cortex-M micro-processors'''.&lt;br /&gt;
&lt;br /&gt;
It was developed by O.C.E. Technology with support from the European Space Agency (ESA) under project 4000127901/19/NL/AS and 4000135473/21/NL/GLC/js.&lt;br /&gt;
&lt;br /&gt;
This document describes the features and use of OCEOS, and details its behavior and system calls.&lt;br /&gt;
&lt;br /&gt;
*Real time software is often written as a set of trap/interrupt handlers and tasks managed by a RTOS.&lt;br /&gt;
*The trap/interrupt handlers start due to anomalous conditions or external happenings. They carry out the immediately necessary processing, and may ask the RTOS start a task to complete the processing.&lt;br /&gt;
*The RTOS starts tasks and schedules them for execution based on priority. In hard real time systems scheduling must ensure that each task completes no later than its deadline. Being early can also be a problem. &lt;br /&gt;
*OCEOS provides a timed output service (software timers) that allows an output be set for a precise system time independently of scheduling.&lt;br /&gt;
*OCEOS supports up to 255 tasks, and up to 15 current start requests for each task. &lt;br /&gt;
**Each task has a fixed priority. &lt;br /&gt;
**There are 254 task priorities, 1 (highest task priority) to 254 (lowest task priority). &lt;br /&gt;
**More than one task may have the same priority. &lt;br /&gt;
**Tasks of the same priority are FIFO scheduled.&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
Time slicing between tasks does not occur in OCEOS.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
*In OCEOS each task has a pre-emption threshold. A task can only be pre-empted by a task with a higher priority than this threshold. Pre-emptions and any traps/interrupts that occur will delay a task’s completion and potentially cause it to miss its deadline. Careful analysis is needed to ensure that task deadlines are always met.&lt;br /&gt;
*OCEOS supports this analysis and allows relatively simple determination of worst case behaviour.&lt;br /&gt;
*Problems such as unbounded priority inversion, chained blocking, and deadlocks cannot occur in OCEOS.&lt;br /&gt;
*OCEOS provides mutual exclusion semaphores (mutexes) to protect critical shared code or data, and inter-task communication using counting semaphores and data queues.&lt;br /&gt;
*A system state variable provides a summary of the current state of the system. &lt;br /&gt;
*Error conditions such as missed deadlines are logged and the system state variable updated. If the system state is not normal a user defined error handling function may be called and actions taken such as disabling a task or resetting the system.&lt;br /&gt;
*OCEOS does not allow dynamic creation of tasks at run time. &lt;br /&gt;
*Virtual memory is not supported.&lt;br /&gt;
*OCEOS is based on the Stack Resource Policy extension of the Priority Ceiling Protocol [https://www.math.unipd.it/~tullio/RTS/2009/Baker-1991.pdf Baker 1991].&lt;br /&gt;
*OCEOS is provided as a library and is statically linked with an application. &lt;br /&gt;
*Services not needed by an application are omitted by the linker.&lt;br /&gt;
&lt;br /&gt;
[[File:Oceos.png|800px]]&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Purpose of the Software&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
OCEOS is a real-time operating system suitable for use in single CPU hard real-time systems. Its design excludes potential problems such as unbounded priority inversion, chained blocking, and deadlocks. It is compact and uses only a single system stack rather than a stack for each task. It schedules up to 255 fixed priority tasks and allows use of mutual exclusion semaphores, counting semaphores and data queues. Its data areas are statically allocated and provide information on task execution that can be accessed at any time. Data outputs and task start requests can be specified to occur at a given system time in microseconds independent of scheduling. A system log and optional context switch log are part of error detection and handling.&lt;br /&gt;
&lt;br /&gt;
OCEOS is an object library for target architecture which provides directives to schedule fixed priority tasks, and supporting mutexes, semaphores, data queues, timed outputs, and interrupt handling.&amp;lt;br&amp;gt;&lt;br /&gt;
There are also directives for logging, error handling, GR716 memory protection and GR716 watchdog control. Only those components used by the application are linked into the executable.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Main Features&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
*Fixed priority preemptive scheduling&lt;br /&gt;
*Based on Stack Resource Policy – unbounded priority inversion, chained blocking, and deadlocks cannot occur&lt;br /&gt;
*Deterministic processing&lt;br /&gt;
*Fast real-time performance&lt;br /&gt;
*Single stack rather than separate stack for each task&lt;br /&gt;
*Small code footprint ( &amp;lt;10 kBytes for scheduling and mutex)&lt;br /&gt;
*Inter-task communication (Counting Semaphores and Data Queues)&lt;br /&gt;
*Synchronisation (Mutexes)&lt;br /&gt;
*Task preemption level&lt;br /&gt;
*Interrupt support (most of the directives can be called from IRQ handlers)&lt;br /&gt;
*Very short time for disabling interrupts&lt;br /&gt;
*Very low interrupt latency&lt;br /&gt;
*Nested interrupts support&lt;br /&gt;
*High precision timed actions (Software Timers) for data output and task start at pricise time&lt;br /&gt;
*Supports SPARC V8 LEON2/3/4 and ARM Cortex-M single core targets&lt;br /&gt;
*Fault Detection, Isolation and Recovety&lt;br /&gt;
*GR716 Memory protection functionality&lt;br /&gt;
*Enhancements for Cobham-Gaisler GR716 applications&lt;br /&gt;
*Sample Applications for Quick start&lt;br /&gt;
*Online Documentation&lt;br /&gt;
*Tutorial applications to demonstrate main features of OCEOS&lt;br /&gt;
*DMON debug tool support (execution timeline, CPU usage and profiling, commands to display information for OCEOS modules)&lt;br /&gt;
*Support &amp;amp; ISVV services available from OCE Technology Ltd.&lt;br /&gt;
*MISRA C Compliant&lt;br /&gt;
*Developed to ECSS Category B and ISO 26262 standards&lt;br /&gt;
*Developed in cooperation with European Space Agency (ESA)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- == &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Memory Requirements&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
Memory usage depends on microcontroller, OCEOS modules and features, compilers and optimization level. &lt;br /&gt;
&lt;br /&gt;
Table below provides memory requirements for different targets. &lt;br /&gt;
Compiled with GNU GCC and optimization level 3. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Memory requirements for .text section of OCEOS, bytes&lt;br /&gt;
|-&lt;br /&gt;
! Section !! OCEOS Module !! (-O3) Size ARM Cortex-M7(thumb) !! (-O3) Size GR716 (REX) !! (-O3) Size LEON4&lt;br /&gt;
|-&lt;br /&gt;
| .text|| oceos_pendsv_handler.o      || 208           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| initialisation.o            || 2816          ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| oceos_start.o               || 1460          ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| interrupt.o                 || 44            ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| tasks.o                     || 3372          ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| task_create.o               || 400           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| task_disable.o              || 220           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| task_enable.o               || 144           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| task_info.o                 || 160           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| task_self.o                 || 76            ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| task_utils.o                || 192           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| task_kill.o                 || 108           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| logging.o                   || 400           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| logging_reset.o             || 176           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| logging_add.o               || 244           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| logging_remove.o            || 180           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| logging_size.o              || 72            ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| logging_utils.o             || 448           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| oceos_timer.o               || 340           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| cpu_sleep.o                 || 208           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| oceos_check_address_space.o || 4             ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
|      || '''Total Kernel'''          ||               ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| dataq.o                     || 284           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| dataq_clear.o               || 364           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| dataq_read_restart.o        || 260           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| dataq_read_restart_timeout.o|| 404           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| dataq_read_continue.o       || 140           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| dataq_write.o               || 684           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
|      || '''Total Dataq'''           ||               ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| mutex.o                     || 164           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| mutex_utils.o               || 608           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
|      || '''Total Mutex'''           ||               ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| semaphore.o                 || 268           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| semaphore_reset.o           || 304           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| semaphore_restart.o         || 264           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| semaphore_restart_timeout.o || 404           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| semaphore_continue.o        || 148           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| semaphore_signal.o          || 584           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
|      || '''Total Semaphore'''       ||               ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| timed_action.o              || 2136          ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| timed_action_init.o         || 208           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| timed_action_sem_remove.o   || 220           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| timed_action_dataq_remove.o || 240           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| timed_action_jobs.o         || 200           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| timed_action_output.o       || 184           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| timed_action_reset.o        || 320           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| timed_action_get_number.o   || 172           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| timed_action_jobs_remove.o  || 116           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| timed_action_output_remove.o|| 84            ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| timed_action_timer.o        || 96            ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| task_timed_start.o          || 828           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
|      || '''Total Timed Actions'''   ||               ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| oceos_isr_cs_log.o          || 628           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
|      || '''Total'''                 || 21811         ||                       ||&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Data Area Layouts&amp;lt;/span&amp;gt; ==&lt;br /&gt;
The design of OCEOS makes the contents of its data areas readily visible to an application. It is straightforward to determine the details of state of the system should it be necessary to do so.&amp;lt;br&amp;gt;&lt;br /&gt;
Each data area is made up of a number of fields whose sizes depend on the particular application but whose general layout is invariant.&amp;lt;br&amp;gt;&lt;br /&gt;
The layout of each area is described in ''oceos_areas.h'' which also provides the offset at which each field in an area is located if the above labels are defined before ''oceos_areas.h'' is included.&lt;br /&gt;
&lt;br /&gt;
Each field starts at a 32-bit boundary, so treating an area as an array of 32-bit words any field can be accessed by simply use the offset as an index into the array.&lt;br /&gt;
&lt;br /&gt;
Application developer must provide OCEOS with three data areas:&lt;br /&gt;
* Log data area&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S     0x100  // Number of words; Application dependent, must be modified by user &lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Fixed data area&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S   0x200  // Number of words; Application dependent, must be modified by user &lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Dynamic data area&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S     0x200  // Number of words; Application dependent, must be modified by user &lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
User can calculate required memory for each data area using following methods:&amp;lt;br&amp;gt;&lt;br /&gt;
* Use OCEOS provided Excel spread sheet. It can be downloaded [[Media:OCEOS_Config.xlsx | HERE]].&lt;br /&gt;
* Use ''oceos_areas.h'' header file &lt;br /&gt;
* Set values as big as possible, run application and use DMON command '''''oceos info''''' to display sizes of each data area in words. Update variables with these sizes.&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 DMON &amp;gt; oceos info&lt;br /&gt;
 Struct Field Name : *system_log_ptr                :: location 0x40016444 :: pointer 0x4001A0E0 :: size 0x109 :: sentinel OK&lt;br /&gt;
 Struct Field Name : *data_fixed_ptr                :: location 0x40016448 :: pointer 0x4001643C :: size 0x59  :: sentinel OK&lt;br /&gt;
 Struct Field Name : *data_dynamic_ptr              :: location 0x4001644C :: pointer 0x400180E0 :: size 0x258 :: sentinel OK&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Add function described below to application to display sizes of data areas. This function should be called after [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]].&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
#define WORDS_USED_OFFSET       1U &lt;br /&gt;
&lt;br /&gt;
void display_data_area_sizes() {&lt;br /&gt;
	&lt;br /&gt;
  printf(&amp;quot;Log data area U32s = %p\n&amp;quot;,log_data[WORDS_USED_OFFSET]);&lt;br /&gt;
  printf(&amp;quot;Fixed data area U32s = %p\n&amp;quot;,fixed_data[WORDS_USED_OFFSET]);&lt;br /&gt;
  printf(&amp;quot;Dynamic data area U32s = %p\n&amp;quot;,dynamic_data[WORDS_USED_OFFSET]);&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
'''OCEOS data areas layout'''&lt;br /&gt;
 [[File:oceos data areas layout.jpg|none]] &lt;br /&gt;
'''OCEOS system data graph'''&lt;br /&gt;
 [[File:oceos memory layout diargam.jpg|none]]&lt;br /&gt;
&lt;br /&gt;
= &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Main Concepts'''&amp;lt;/span&amp;gt; =&lt;br /&gt;
&lt;br /&gt;
An application that uses OCEOS typically starts at main(), performs device initialization and other activities including setting up interrupt handlers, then starts OCEOS in two phases, an initialization phase and a scheduling phase. Tasks, mutexes etc. are only created in the initialization phase, resulting in a fixed data structure that is passed to the scheduling phase. OCEOS normally does not return to the application but will do so if it detects a fatal error.&lt;br /&gt;
&lt;br /&gt;
The specific application determines the tasks, mutexes and other OCEOS components used.&lt;br /&gt;
&lt;br /&gt;
The interrupt/trap handlers respond to events, do the immediately necessary processing, and typically ask OCEOS to start a task to complete the processing.&lt;br /&gt;
&lt;br /&gt;
OCEOS then creates an execution instance of the task, a ‘job’, and either puts it into immediate execution or on the ready queue or the timed jobs queue waiting to be scheduled for execution.&lt;br /&gt;
&lt;br /&gt;
OCEOS schedules jobs based on their priority and may pre-empt the processor from a job with a lower pre-emption threshold before that job completes in order to start a higher priority job.&lt;br /&gt;
&lt;br /&gt;
OCEOS maintains a system priority ceiling based on currently locked resources and the pre-emption threshold of the currently executing job. Only jobs with higher priority than this ceiling can pre-empt.&lt;br /&gt;
&lt;br /&gt;
Jobs with the same priority are scheduled according to time of arrival on the ready queue. Time slicing or pre-emption between jobs of the same priority does not take place.&lt;br /&gt;
&lt;br /&gt;
A job may have a deadline by which it must complete. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
It is the responsibility of the software developer to assign task priorities so that all jobs are guaranteed to meet their deadlines&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In OCEOS mutual exclusion of tasks is supported by mutexes. Counting semaphores and data queues support task synchronization and the exchange of data between jobs.&lt;br /&gt;
&lt;br /&gt;
Task start requests and data outputs (software timers) can be set to occur independently of scheduling at a given system time in microseconds.&lt;br /&gt;
&lt;br /&gt;
OCEOS maintains a system state variable and system log. If the state variable is not normal OCEOS may call a user defined function to deal with whatever condition has occurred.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tasks&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
In OCEOS all tasks are defined before scheduling begins and each task assigned a fixed priority, a pre-emption threshold, a current jobs limit, a maximum start to completion time, and an expected minimum inter start request time.&lt;br /&gt;
A task’s pre-emption threshold limits the tasks that can pre-empt it to those with higher priority than this threshold. Tasks with short run times can use this to avoid context switch overheads.&lt;br /&gt;
&lt;br /&gt;
Each task has two main states, enabled or disabled. OCEOS provides system calls to change task state. The state is usually enabled when the task is created, but can be initially disabled.&amp;lt;br&amp;gt;&lt;br /&gt;
A disabled task will not be executed, and any attempt to start it will be logged and the system state variable updated.&lt;br /&gt;
&lt;br /&gt;
A request to start an enabled task creates an execution instance of the task, a ‘job’. A count is kept for each task of the number of times it has been started, i.e. total number of jobs created.&amp;lt;br&amp;gt;&lt;br /&gt;
Multiple jobs of the same task can be in existence simultaneously. A limit for the maximum number of these current jobs is set when a task is created, the ‘current jobs limit’.&amp;lt;br&amp;gt;&lt;br /&gt;
Each task has a current jobs count. This increments each time a task is started and decrements on job completion unless completion creates a further job from this task.&amp;lt;br&amp;gt;&lt;br /&gt;
A further execution instance of a task is not created if the current jobs count has reached the current jobs limit. Such job creation failures are logged and the system state updated.&amp;lt;br&amp;gt;&lt;br /&gt;
For each task a record is kept of the shortest time between attempts to create a new job, and a record of the maximum time between these attempts.&amp;lt;br&amp;gt;&lt;br /&gt;
For each task a record is kept also of the maximum time a job was waiting before starting, the minimum execution time, the maximum execution time, the maximum time from job creation to completion, and the maximum number of job pre-emptions. The system state variable is updated if necessary.&lt;br /&gt;
&lt;br /&gt;
Task chaining is supported. A job can create a new job and pass this to the scheduler or place it on the timed actions queue.&lt;br /&gt;
&lt;br /&gt;
Tasks provide a start address for a termination routine for use if task execution must be abandoned.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Jobs&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
The request to start a task initializes a 'job', an execution instance of the task. A parameter is provided to allow an optional structure pointer be passed to the job.&amp;lt;br&amp;gt;&lt;br /&gt;
A job can require varying times to complete, with one exception its maximum execution time and maximum resource requirements are finite and known at compile time.&amp;lt;br&amp;gt;&lt;br /&gt;
This one exception is the unique lowest priority ‘idle job’, which if it exists has no execution time limitation. If there is no idle task OCEOS will place the CPU in sleep mode.&amp;lt;br&amp;gt;&lt;br /&gt;
Typically the ‘idle job’ is not idle, but used for system monitoring, logging, and initiating system correction activities. To save power it may put the CPU in sleep mode waiting for interrupts.&lt;br /&gt;
&lt;br /&gt;
A job has two principal states, pending and active. A pending job has not started execution and is either on the ready queue or on the pending jobs queue of a semaphore or data queue, or on the timed actions queue. Only pending jobs wait on resources. In OCEOS a pending job becomes active when it first starts execution. An active job is either running on the CPU or on the ready queue after being pre-empted.&amp;lt;br&amp;gt;&lt;br /&gt;
An active job may have to wait on the ready queue for the CPU but never has to wait for any other resource and is never on a pending jobs queue.&lt;br /&gt;
&lt;br /&gt;
For each job a record is kept of the time it was created, the time it became active, the execution time, the time it completed, and the number of times it was pre-empted.&lt;br /&gt;
&lt;br /&gt;
When a job completes, these job records are used to update the task records.&lt;br /&gt;
&lt;br /&gt;
Data can be passed between jobs of the same or different tasks by using statically allocated variables, counting semaphores, or data queues.&lt;br /&gt;
&lt;br /&gt;
A job may create another job and place this on the ready queue or on the timed actions queue.&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
If job can not continue because semaphore count is zero or data queue is empty, the job is put on pending queue for that semaphore or data queue and restarted when semaphore count is incremented or data is written to data queue. The user must take care to save information in data section, so the restarted job could continue without loss of already acquired data.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt; Ready Queue&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
This priority queue contains pending and active jobs ordered highest priority first, and within priority earliest arrival first.&amp;lt;br&amp;gt;&lt;br /&gt;
The scheduler places the first job on this queue into execution if and only if its priority is higher than the system priority ceiling. When it does so it updates the system priority ceiling to the pre-emption threshold of this job.&lt;br /&gt;
&lt;br /&gt;
OCEOS places pending jobs on this queue due to an interrupt or trap, or as a result of a system call from the current job, a semaphore signal or queue write, or a timeout.&amp;lt;br&amp;gt;&lt;br /&gt;
Each job in the Ready Queue is tagged with an ‘origin’ giving how the job came to be placed on the Ready Queue including time and identification of any other queue from which it was removed.&amp;lt;br&amp;gt;&lt;br /&gt;
There can be multiple occurrences of jobs from the same task on the Ready Queue, each with its origin. Initially this queue either contains the Idle Job, which must have the lowest priority, or is empty.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Timed Actions Queue&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
This is a priority queue of pending actions (software timers) and their associated times, with queue priority based on these times.&amp;lt;br&amp;gt;&lt;br /&gt;
It is linked to a high priority hardware timer which is set to interrupt at the time of the first action on the priority queue.&amp;lt;br&amp;gt;&lt;br /&gt;
When this interrupt occurs actions on the queue within a timing tolerance of the current time are carried out and the timer is reset to interrupt at the start time of the earliest remaining action.&amp;lt;br&amp;gt;&lt;br /&gt;
If the action is a task start request then at the set time the associated job is transferred to the ready queue, its origin set to timeout, and it is also removed from the pending list of any counting semaphore or data queue on which it is present. If the job is now the highest priority job on the ready queue it is started immediately, otherwise it must wait until that is the case.&amp;lt;br&amp;gt;&lt;br /&gt;
If the action is a data output then at the set time it is performed immediately.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;System Priority Ceiling&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
The value of this integer is the maximum priority of the priority ceilings of currently locked mutexes and the pre-emption threshold of the currently executing job. It is not directly accessible to an application.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Scheduling&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
OCEOS schedules jobs, i.e. execution instances of tasks created as a result of task start requests.&amp;lt;br&amp;gt;&lt;br /&gt;
The scheduler places a job into execution if and only if its priority is higher than the system priority ceiling. When it does so it updates the system priority ceiling to the pre-emption threshold of this job.&amp;lt;br&amp;gt;&lt;br /&gt;
Scheduling is pre-emptive and based on priority. The scheduler may pre-empt the processor from a lower priority job before that job completes to allow a higher priority job be started.&lt;br /&gt;
&lt;br /&gt;
Jobs with the same priority are scheduled based on the order of their arrival on the ready queue. Time slicing or pre-emption between jobs of the same priority does not occur.&amp;lt;br&amp;gt;&lt;br /&gt;
A job with a very short run time can avoid context switch overheads by having a high pre-emption threshold. This also allows pre-emption by some or all higher priority tasks be prevented. Such jobs with high pre-emption thresholds are scheduled based on their priority as usual.&amp;lt;br&amp;gt;&lt;br /&gt;
In OCEOS a wait for a mutex causes the system priority ceiling to be raised to the priority ceiling of the mutex unless it was already higher. The system priority ceiling returns to its previous value when the mutex is signaled.&lt;br /&gt;
&lt;br /&gt;
As a result the scheduler will not start any task that waits on that mutex until the mutex has been returned, as the mutex ceiling is the priority of the highest priority task that uses the mutex.&amp;lt;br&amp;gt;&lt;br /&gt;
(Instead of a higher priority job pre-empting a lower priority job but before termination returning control to a lower priority job and waiting for it to return a mutex, the wait for the mutex is done first.)&lt;br /&gt;
&lt;br /&gt;
In OCEOS context switching between tasks is minimized. A lower priority job only resumes execution when a higher priority job has completed, thus allowing stack sharing.&amp;lt;br&amp;gt;&lt;br /&gt;
In OCEOS problems such as priority inversion, chained blocking, and deadlocks cannot occur, all tasks can share the same stack thus saving memory, and schedulability analysis is simplified.&lt;br /&gt;
&lt;br /&gt;
Unnecessary blocking will occur for a job that does not use a mutex if it has a priority lower than the mutex priority ceiling and the mutex is currently held by a lower priority job.&amp;lt;br&amp;gt;&lt;br /&gt;
This un-necessary blocking may seldom occur, is limited in duration, and can be avoided by setting task priorities appropriately.&lt;br /&gt;
&lt;br /&gt;
This scheduling approach is based on the Stack Resource Policy extension of the Priority Ceiling Protocol [https://www.math.unipd.it/~tullio/RTS/2009/Baker-1991.pdf Baker 1991].&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Shared Resources&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
Many data structures cannot be fully accessed with a single instruction. Errors can result if a job using such a structure is pre-empted by another job that also uses the structure.&amp;lt;br&amp;gt;&lt;br /&gt;
To address this OCEOS provides up to 63 mutual exclusion semaphores ([[OCEOS/oceos inter-task communication/mutex|mutex]]). Each shared data structure or critical code segment typically is associated with its own mutex.&amp;lt;br&amp;gt;&lt;br /&gt;
Any job that uses a shared item should first acquire its mutex from OCEOS, and when finished with the item return the mutex. The number of instructions for which the mutex is held must be finite.&amp;lt;br&amp;gt;&lt;br /&gt;
OCEOS allows a mutex be held by only one job at any one time. A job that uses a shared data structure or critical code segment can use an associated mutex to exclude all other jobs.&amp;lt;br&amp;gt;&lt;br /&gt;
N.B. An OS does not prevent a shared resource being accessed if no attempt is made to acquire its mutex. The software developer must ensure this is done before the shared resource is used.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Inter-Job Communication&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
OCEOS provides two types of inter-job communication, counting semaphores and data queues. Semaphores and data queues are handled by OCEOS in a way different to many other OS.&amp;lt;br&amp;gt;&lt;br /&gt;
In most OS a job that waits on a zero semaphore or tries to read an empty data queue may be blocked at that point and wait there indefinitely or with an optional timeout.&amp;lt;br&amp;gt;&lt;br /&gt;
In OCEOS an active job may be pre-empted but cannot otherwise be blocked, so three options are provided in case a counting semaphore is zero when waited on or a data queue is empty when read.&lt;br /&gt;
&lt;br /&gt;
One option results in a value always being returned and the job continuing. The returned value will indicate that the semaphore was zero or queue empty, and the job can take this into account.&amp;lt;br&amp;gt;&lt;br /&gt;
In the other options, if the semaphore is zero or queue empty the job terminates and will restart from its beginning when the semaphore is signaled or queue written, or after an optional timeout.&lt;br /&gt;
&lt;br /&gt;
When the job becomes active again after a timeout and again encounters the second option the behavior is as with the first option, the job continues and takes into account that a timeout has occurred.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
Because a job restarts when a resource becomes available rather than waiting at the point where it sought the resource any local data developed up to that point will be lost unless stored non-locally for use after the restart. If required this can be done using static variables or structures, or using data queues or counting semaphores.&lt;br /&gt;
&amp;lt;/blockquote &amp;gt;&lt;br /&gt;
&lt;br /&gt;
In OCEOS event communication between tasks or between tasks and interrupt handlers is done typically by using counting semaphores.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Pending Jobs Queue&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
Each counting semaphore and data queue has an associated queue of pending jobs that are waiting for that semaphore or queue. Pending jobs also wait on the timed actions queue.&amp;lt;br&amp;gt;&lt;br /&gt;
Pending jobs queues contain only pending jobs and not active jobs, i.e. only jobs waiting to start execution.&amp;lt;br&amp;gt;&lt;br /&gt;
A pending job can be on a semaphore pending jobs queue or on a data queue pending jobs queue and also on the timed actions queue.&lt;br /&gt;
&lt;br /&gt;
The amount of time a job can spend on a semaphore or data queue pending jobs queue is of indefinite duration unless it is also on the timed actions queue.&lt;br /&gt;
&lt;br /&gt;
When a job is removed from a semaphore or data queue pending jobs queue its origin is set accordingly. It is also removed from the timed actions queue if present.&lt;br /&gt;
&lt;br /&gt;
When a timeout occurs and a job is removed from the timed actions queue its origin is set accordingly and it also is removed from a semaphore or data queue pending jobs queue if present.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
Mutexes do not having pending job queues. A pending job waiting for a mutex waits on the ready queue. Such waits are expected to be of short duration.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If it is necessary to pass data to a later job a job can do this before termination using static variables, static structures, data queues or counting semaphores.&lt;br /&gt;
&lt;br /&gt;
All jobs on a pending jobs queue are moved to the ready queue in the order of their arrival on the pending jobs queue before any of them is scheduled. Usually only one job is waiting on a pending jobs queue, if more than one a lower priority job may have to return to the pending jobs queue because a higher priority job or an earlier job has consumed the item. &lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;System State&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
OCEOS maintains a system state variable that is updated whenever there is anomalous behavior such as attempting to create more than the allowed number of jobs or writing to a queue that is full.&amp;lt;br&amp;gt;&lt;br /&gt;
If this variable is not its normal value, depending on the anomaly OCEOS may call a user defined function to deal with the anomaly.&amp;lt;br&amp;gt;&lt;br /&gt;
This typically reads the system log and the system state variable to determine the background to the detected anomaly.&lt;br /&gt;
&lt;br /&gt;
Please consult the header file codes.h for the system state variable codes. These include anomalies such as (the indexes below are not the codes used):&amp;lt;br&amp;gt;&lt;br /&gt;
* An attempt to start a disabled task&lt;br /&gt;
* An attempt to execute a task when its jobs limit is already reached.&lt;br /&gt;
* Job time from creation to completion exceeds allowed maximum for a task (deadline missed).&lt;br /&gt;
* Minimum time between job creations is less than the allowed minimum for task&lt;br /&gt;
* Ready queue unable to accept job as result of being full&lt;br /&gt;
* Mutex wait() when mutex already held&lt;br /&gt;
* Mutex signal() when not already held&lt;br /&gt;
* Mutex not returned before job terminates&lt;br /&gt;
* Attempt to add job to semaphore pending list when list full&lt;br /&gt;
* Data queue write when queue already full&lt;br /&gt;
* Attempt to add job to queue pending list when list full&lt;br /&gt;
* Timed job start write when timed actions queue already full&lt;br /&gt;
* Timed job start late job transfer to scheduler&lt;br /&gt;
* Timed output request when timed actions queue already full&lt;br /&gt;
* Timed output late&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;System Log&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
This contains time stamped records of anomalies detected during execution. It is structured as a circular buffer. System calls are provided to initialize the log, set its maximum size, and return the number of entries.&lt;br /&gt;
&lt;br /&gt;
OCEOS will call a user defined function when the log is approximately 75% full.&lt;br /&gt;
&lt;br /&gt;
= &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Definitions and Abbreviated Terms'''&amp;lt;/span&amp;gt; =&lt;br /&gt;
&lt;br /&gt;
The following gives terminology used in relation to OCEOS RTOS and some clarification notes.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''action''':&amp;lt;/span&amp;gt; something to be done at a specified system time.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS an action is done independently of task scheduling and is either a task start request or output of a value to an address.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''area''':&amp;lt;/span&amp;gt; a contiguous block of memory used for OCEOS internal data.&amp;lt;br&amp;gt;&lt;br /&gt;
 OCEOS does not use dynamic memory allocation to provide space for its internal data but instead sets up three statically defined areas based on the ASW configuration.&lt;br /&gt;
 The fixed data area holds information that does not change after all tasks etc. are created, the dynamic area holds information about tasks, jobs, etc. that changes as scheduling takes place, and the log area holds the system  state variable and the system log, which are always present, and if used the context switch log. The start addresses of the three areas are given by the ASW and must be 32-bit word aligned. Starting from these addresses each area is created by OCEOS as a block of 32-bit words that starts with OCEOS_VERSION followed by the count in words of the area size and ending with END_SENTINEL. The size of each area depends on the characteristics of the application, the number of tasks, mutexes, etc., and does not change once set up. OCEOS provides a header file oceos_areas.h which makes area sizes and field offsets available as defined constants if certain application characteristics are predefined as constants. OCEOS also uses a single system stack and a small amount of space on the heap.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''atomic''':&amp;lt;/span&amp;gt; an operation which once started does not allow other actors carry out the operation until the current operation has completed.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''application program interface (API)''':&amp;lt;/span&amp;gt; describes the application’s interface with OCEOS, usually referred to here as ‘directives’.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''context switch''':&amp;lt;/span&amp;gt; the change from executing the instruction codes of one task to executing those of another task.&amp;lt;br&amp;gt;&lt;br /&gt;
 Done by the OCEOS scheduler when it pre-empts a task.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''context switch latency''':&amp;lt;/span&amp;gt; the time taken to remember essential current task information and to set up or restore the new task’s information and put it into execution.&amp;lt;br&amp;gt;&lt;br /&gt;
 Please also refer to scheduling latency.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''context switch log''':&amp;lt;/span&amp;gt; a time-stamped record of context switches and switches to and from interrupt handlers for use by a debug monitor such as DMON.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''counter''':&amp;lt;/span&amp;gt; an unsigned integer typically updated by an interrupt or system call.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS a counter may involve 8 bits, 16 bits or 32 bits.&lt;br /&gt;
 In OCEOS a counter does not wrap around through zero but remains at its maximum/minimum value when this has been reached. &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''counting semaphore''':&amp;lt;/span&amp;gt; used to synchronize different tasks.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS a counting semaphore has a 32-bit counter, a pending jobs list, a semaphore create directive oceos_sem_create used only in system initialisation, a directive to return the counter value, a directive to return the number of pending list jobs, and four atomic directives, oceos_sem_signal, oceos_sem_wait_continue, oceos_sem_wait_restart, and oceos_sem_wait_restart_timeout.&lt;br /&gt;
 Signal operations and wait operations on a semaphore usually occur in different tasks.&lt;br /&gt;
 In OCEOS waiting on a semaphore has three options: continue, restart, restart with wait timeout. If the semaphore counter is non-zero all three options behave in the same way, decrementing the counter and returning a status code. If the semaphore counter is zero what happen depends on the option the ASW has chosen.&lt;br /&gt;
 N.B. In OCEOS a job does not block at the point where it does a wait operation on a zero semaphore, depending on the option chosen it either continues or terminates and restarts later. If a job uses the restart option, any local data at that point that is to be available after the job restarts needs to be stored globally as local data is lost when the job terminates.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''critical section''':&amp;lt;/span&amp;gt; a sequence of instructions that should not be in use by more than one task at a time.&amp;lt;br&amp;gt;&lt;br /&gt;
 Usually protected by a mutex that is locked at the start of the critical section and released at the end.&lt;br /&gt;
 N.B. Critical sections should be as short as possible.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''data queue''':&amp;lt;/span&amp;gt; in OCEOS a queue of non-null void pointers used to exchange data between tasks and to synchronize tasks.&amp;lt;br&amp;gt;&lt;br /&gt;
 It has a oceos_dataq_create directive that is only used during system initialisation, a data queue, a pending jobs list, a directive that returns the number of pointers on the data queue, a directive that returns the number of jobs on the pending list, and four atomic directives, oceos_dataq_write, oceos_dataq_read_continue,  oceos_dataq_read_restart, and oceos_dataq_read_restart_timeout.&lt;br /&gt;
 Write operations and read operations on a queue usually occur in different tasks.&lt;br /&gt;
 In OCEOS reading a queue has three options: continue, restart, restart with wait timeout. If the queue is non empty all three options behave in the same way, returning the pointer at the head of the queue. If the queue is empty what happen depends on the option the ASW has chosen.&lt;br /&gt;
 N.B. In OCEOS a job does not block at the point where it does a read operation on an empty queue, depending on the option chosen it either continues or terminates and restarts later. If a job uses the restart option, any local  data at that point that is to be available after the job restarts needs to be stored globally as local data is lost when the job terminates.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''deadlock''':&amp;lt;/span&amp;gt; a scheduling condition where jobs cannot proceed because each holds a resource the other needs.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS deadlocks cannot occur when mutexes are configured correctly.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''directive''':&amp;lt;/span&amp;gt; used by the application software to call an individual OCEOS function.&amp;lt;br&amp;gt;&lt;br /&gt;
 Directives provide control over tasks, message queues, semaphores, memory, timers etc.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''dynamic area''':&amp;lt;/span&amp;gt; area used by OCEOS for internal data that changes as part of normal scheduling operations, the area contents change but its size is constant.&amp;lt;br&amp;gt;&lt;br /&gt;
 It contains information such as e.g. the current system priority ceiling, the ready queue, states of tasks, jobs, mutexes etc.&lt;br /&gt;
 It is set up and initialised by oceos_start based on the fixed area information passed to it. Please also refer to ‘area’ above.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''error handling''':&amp;lt;/span&amp;gt; actions taken when OCEOS detects that a problem has occurred.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS error handling may involve one or a combination of (i)returning an appropriate status code (ii) making a system log entry (iii) updating the system state variable (iv) calling a user defined problem handling function (v) ending scheduling and exiting. If called the problem handling function can use the log, the system state variable, task and job timings and other data to determine the action that should be taken. If OCEOS detects corruption of its data areas it exits and returns to the ASW, which can access the system log, system state variable, and other information such as task timings.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''error hook''':&amp;lt;/span&amp;gt; a reference to the user defined function called when an abnormal condition is detected.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''event''':&amp;lt;/span&amp;gt; in some OS, but not in OCEOS, a job can suspend its own execution until a specified event occurs.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS an active job may be pre-empted by a higher priority job but never suspends itself.&lt;br /&gt;
 In OCEOS similar functionality is provided by a wait restart on a counting semaphore that is signalled later by an interrupt handler.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''fixed area''':&amp;lt;/span&amp;gt; area used by OCEOS for internal data that is defined in OCEOS initialisation and as tasks, mutexes etc. are created, this area does not change after oceos_init_finish is called.&amp;lt;br&amp;gt;&lt;br /&gt;
 It contains information such as number of tasks, task priorities, priority ceilings of mutexes, etc. The area is initialised by oceos_init and finalised after all tasks etc. have been created by oceos_init_finish, which adds an XOR checksum in the penultimate word. The fixed area is passed to oceos_start, which begins scheduling. Please also refer to ‘area’ above.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''hook''':&amp;lt;/span&amp;gt; a reference to a user defined function called by the operating system in certain conditions.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''idle job''':&amp;lt;/span&amp;gt; an execution instance of the unique lowest priority task, it is allowed to run indefinitely.&amp;lt;br&amp;gt;&lt;br /&gt;
 As OCEOS does not use time slicing and lower priority jobs wait for higher priority jobs to complete all other jobs should terminate after a finite time period.&lt;br /&gt;
 Typically this ‘idle job’ is not idle, but used for managing a watchdog timer, system monitoring and initiating system correction activities. To save power it may put the CPU in sleep mode waiting for interrupts (after disabling the watchdog if one is used).If no idle job is present OCEOS puts the CPU in sleep mode when no job is ready to run.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''initialization code''':&amp;lt;/span&amp;gt; this code executes when the CPU is reset and before main is called.&amp;lt;br&amp;gt;&lt;br /&gt;
 It is part of the BSP system used before main in the ASW.&lt;br /&gt;
 It is not part of OCEOS.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''interrupt''':&amp;lt;/span&amp;gt; a form of trap caused by an input to the CPU from an interrupt controller due to a change in state of one of the external links connected to the interrupt controller.&amp;lt;br&amp;gt;&lt;br /&gt;
 Please refer to ‘trap’.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''interrupt handler''':&amp;lt;/span&amp;gt; the code called when an interrupt occurs.&amp;lt;br&amp;gt;&lt;br /&gt;
 Please refer to ‘trap handler’.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''interrupt latency''':&amp;lt;/span&amp;gt; the time between the occurrence of the external interrupt condition and the execution of the first instruction of the interrupt handler.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''interrupt level''':&amp;lt;/span&amp;gt; the interrupt priority as determined by the CPU architecture and the interrupt controller.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''interrupt nesting''':&amp;lt;/span&amp;gt; occurs when an interrupt handler is interrupted by a higher priority interrupt.&amp;lt;br&amp;gt;&lt;br /&gt;
 Please see 'trap nesting'&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''interrupt service routine''':&amp;lt;/span&amp;gt; the interrupt handler associated with the interrupt.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''job''':&amp;lt;/span&amp;gt; a record of a request to start a task or the resulting execution instance of the task.&amp;lt;br&amp;gt;&lt;br /&gt;
 Please refer to ‘task job’.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''kernel mode''':&amp;lt;/span&amp;gt; the CPU mode in which all instructions are available for use and all physical memory addresses accessible.&amp;lt;br&amp;gt;&lt;br /&gt;
 N.B. When using OCEOS both the ASW and OCEOS are expected to run in kernel mode.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''log area''':&amp;lt;/span&amp;gt; an OCEOS memory area used to store system state information including the system state variable and the system log and if used the context switch log.&amp;lt;br&amp;gt;&lt;br /&gt;
 As this area is usually accessed only when a problem occurs, it may be stored in relatively slow external memory without impacting performance, and if this is non-volatile aspects of OCEOS state are preserved across power cycles.&lt;br /&gt;
 Please also refer to ’area’.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''manager''':&amp;lt;/span&amp;gt; a group of OCEOS directives with related functionality.&amp;lt;br&amp;gt;&lt;br /&gt;
 Managers may be core (used whenever OCEOS is used) or optional (selected or not by the application developer).&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''module''':&amp;lt;/span&amp;gt; OCEOS is structured as independent modules responsible for different OS features.&amp;lt;br&amp;gt;&lt;br /&gt;
 If a module is not used it is omitted at link time.&lt;br /&gt;
 Core manager modules are always present.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''mutex''':&amp;lt;/span&amp;gt; a binary semaphore used to provide mutual exclusion.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS each mutex has a priority ceiling. This is set when the mutex is created to the priority of the highest priority task that uses the mutex. If this is done correctly the design of OCEOS ensures that unbounded priority inversion, chained blocking, and deadlocks cannot occur, a significant advantage compared to most other RTOS.&lt;br /&gt;
 The wait and signal operations used to acquire and release a mutex should occur in pairs in the same task, and in a nested manner if multiple mutexes are used.&lt;br /&gt;
 The number of instruction executions between wait and signal must be finite and should be as short as possible.&lt;br /&gt;
 N.B. Mutexes provide mutual exclusion for tasks and not for interrupt handler code.&lt;br /&gt;
 N.B. The ASW is responsible for associating a mutex with a shared resource and ensuring it is used whenever the shared resource is accessed.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''mutual exclusion''':&amp;lt;/span&amp;gt; it must be possible for a task that is updating a resource to exclude other tasks from accessing the resource until updating is complete.&amp;lt;br&amp;gt;&lt;br /&gt;
 This is usually achieved by associating a specific mutex with each resource, and ensuring that any task that accesses the resource first acquires the mutex (wait) and releases it when access is complete (signal).&lt;br /&gt;
 Please refer to ‘mutex’.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''origin''':&amp;lt;/span&amp;gt; this indicates whence a pending job came when it was transferred to the ready queue.&amp;lt;br&amp;gt;&lt;br /&gt;
 The job may have just been created, or have been transferred from a pending jobs list as a result of a counting semaphore being signalled or data queue being written, or from a timed action queue as a result of a timeout.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''pending jobs list''':&amp;lt;/span&amp;gt; Each counting semaphore and each data queue has a pending jobs list of jobs waiting to be restarted when the resource becomes available.&amp;lt;br&amp;gt;&lt;br /&gt;
 Jobs are added to the list if the restart option is used and an attempt to wait on the semaphore or read the data queue fails.&lt;br /&gt;
 Following a signal or write all jobs on a pending list are transferred to the ready queue in the order in which they were placed on the list (FIFO), and the scheduler is called.&lt;br /&gt;
 Note: In OCEOS a mutex does not have a pending jobs list, jobs are only put into execution if all mutexes they require are free.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''pending jobs queue''':&amp;lt;/span&amp;gt; A queue of jobs organised based on priority rather than on arrival order, with usually no more than one job at a time removed from the queue.&amp;lt;br&amp;gt;&lt;br /&gt;
 The timed actions queue is a priority queue based on activation time.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''pre-empt''':&amp;lt;/span&amp;gt; the scheduler may pre-empt the processor from the currently running job when a job with higher priority than the current system priority ceiling is ready to start.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''pre-emption threshold''':&amp;lt;/span&amp;gt; a task’s pre-emption threshold restricts the tasks that can pre-empt it to those with higher priority than this threshold.&amp;lt;br&amp;gt;&lt;br /&gt;
 Please refer to ‘task pre-emption threshold’.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''priority''':&amp;lt;/span&amp;gt; a measure of urgency or importance.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS priorities range from 0 (highest priority) to 255 (lowesr priority).&lt;br /&gt;
 Priority levels 0 and 255 are reserved for internal OCEOS use.&lt;br /&gt;
 Task priorities are restricted to from 1 (highest) to 254 (lowest).&lt;br /&gt;
 Please refer to ‘task priority’.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''priority ceiling''':&amp;lt;/span&amp;gt; each mutex has a priority ceiling equal to the priority of the highest priority task that uses it.&amp;lt;br&amp;gt;&lt;br /&gt;
 This ceiling is determined by the ASW developer during code development and set when the mutex is created.&lt;br /&gt;
 OCEOS will only start a pending job if its priority is higher than the priority ceilings of all currently locked mutexes.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''priority ceiling protocol''':&amp;lt;/span&amp;gt; an approach to scheduling and to sharing resources.&amp;lt;br&amp;gt;&lt;br /&gt;
 OCEOS is based on an extension of this, the stack resource policy BAK91.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''priority inversion''':&amp;lt;/span&amp;gt; when a higher priority job has to wait in order to allow a lower priority job complete processing a shared resource and return a mutex.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS this wait occurs before the higher priority task starts. The maximum length of the wait can be determined during code development.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''priority inversion (unbounded)''':&amp;lt;/span&amp;gt; if a lower priority job can be pre-empted while holding a mutex the resulting delay to the return of the mutex by the low priority job can cause unbounded delays to a higher priority job that requires the mutex.&amp;lt;br&amp;gt;&lt;br /&gt;
 This cannot occur in OCEOS when mutexes are configured correctly.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''priority queue''':&amp;lt;/span&amp;gt; the order in which elements are removed is based on their priorities rather than on the order in which they arrived on the priority queue.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS the ready queue is a priority queue based on job priority and order of arrival, the timed actions queue is a priority queue based on time.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''queue''':&amp;lt;/span&amp;gt; A first in first out (FIFO) queue such as an OCEOS data queue.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''ready queue''':&amp;lt;/span&amp;gt; a priority queue of jobs with priority based on job priority and within priority on order of arrival.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS this holds references to pending jobs which have not yet started running, to active jobs that have been pre-empted, and to the currently executing job. A job is removed from the ready queue when it terminates.&lt;br /&gt;
 The OCEOS scheduler puts the first job on this queue into execution on the processor if and only if its priority is higher than the current system priority ceiling.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''resource''':&amp;lt;/span&amp;gt; may be a shared resource that can be accessed by different tasks.&amp;lt;br&amp;gt;&lt;br /&gt;
 Shared resources can give rise to many problems, please refer to 'mutual exclusion ' and ‘mutex’.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''running''':&amp;lt;/span&amp;gt; the running job is the job whose instructions are currently being executed on the processor.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS an active job is running unless interrupted or pre-empted, it is never in a suspended state waiting on a resource (other than the CPU).&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''scheduler''':&amp;lt;/span&amp;gt; a central part of an RTOS such as OCEOS, it determines which job should be executed on the processor.&amp;lt;br&amp;gt;&lt;br /&gt;
 In order to allow another job begin the scheduler may pre-empt the processor from the currently executing job.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''scheduling latency''':&amp;lt;/span&amp;gt; the time between the execution of the last instruction used in the old task and the execution of the first instruction used in the new task when the scheduler switches the processor between tasks.&amp;lt;br&amp;gt;&lt;br /&gt;
 It includes the context switch latency and the time taken by other scheduler actions.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''scheduling policy''':&amp;lt;/span&amp;gt; determines whether the currently executing job should be pre-empted.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS this is based on the stack resource policy with fixed task priorities and single resources BAK91. Pre-emption occurs if and only if the priority of the new job to be started is higher than the current system priority ceiling.&lt;br /&gt;
 N.B. By setting appropriate task priorities RMS and other systems can be used with OCEOS.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''semaphore''':&amp;lt;/span&amp;gt; Please refer to ‘counting semaphore’ and also to ‘mutex’.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''shutdown hook''':&amp;lt;/span&amp;gt; address of routine called to shut down the system.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''signal''':&amp;lt;/span&amp;gt; in OCEOS refers to a type of directive used to unlock a mutex or to attempt to increment a counting semaphore.&amp;lt;br&amp;gt;&lt;br /&gt;
 Please refer to ‘mutex’ and ‘counting semaphore’.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''sleep mode''':&amp;lt;/span&amp;gt; activities in the CPU are powered off except those required to monitor external interrupts.&amp;lt;br&amp;gt;&lt;br /&gt;
 When an interrupt is detected the CPU vectors to the corresponding interrupt handler and resumes normal execution.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''software component''':&amp;lt;/span&amp;gt; system settings data, initialisation code, trap handler, application tasks, and applicable OCEOS modules.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''stack resource policy''':&amp;lt;/span&amp;gt; an extension of the priority ceiling protocol that makes unbounded priority inversion, chained blocking and deadlocks impossible when mutexs are configured correctly and allows all tasks to share a single stack rather than requiring a separate stack for each task BAK91.&amp;lt;br&amp;gt;&lt;br /&gt;
 N.B. OCEOS is based on this policy.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''start a task''':&amp;lt;/span&amp;gt; create a job, put this job on the ready queue, and call the scheduler after allowing any interrupt nesting present to unwind.&amp;lt;br&amp;gt;&lt;br /&gt;
 Please see 'task start'&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''status code''':&amp;lt;/span&amp;gt; a code returned when an OCEOS directive is used indicating success or failure.&amp;lt;br&amp;gt;&lt;br /&gt;
 In most cases this is one of a predefined set of codes that indicate the type of problem if a problem has occurred, in one case a problem is indicated by return of a NULL pointer.&lt;br /&gt;
 N.B. The returned status code should always be checked when an OCEOS directive is used.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''suspended''':&amp;lt;/span&amp;gt; no jobs of the task are currently pending or active.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''system log''':&amp;lt;/span&amp;gt; used to record log entries made by OCEOS or by the ASW.&amp;lt;br&amp;gt;&lt;br /&gt;
 Stored in the OCEOS log data area whose start address is given by the application developer.&lt;br /&gt;
 Structured as an array of 64-bit log entries. The maximum number of log entries, which should be in the range 16 to 1024, is given by the application developer, with default 64.&lt;br /&gt;
 The log is treated as a circular buffer and the application developer can define a function to be called when the log becomes ¾ full.&lt;br /&gt;
 Log entries are preserved across system reset and if stored in non-volatile memory across power on-off cycles.&lt;br /&gt;
 Please refer to 'log area'.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''system priority ceiling''':&amp;lt;/span&amp;gt; an integer in the range 0 to 255, for a job to start it must be higher priority than the system priority ceiling.&amp;lt;br&amp;gt;&lt;br /&gt;
 Its value is set to 255 (lowest priority) at system start and subsequently determined by the pre-emption threshold of the currently executing job and the priority ceilings of any mutexes currently held.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''system priority ceiling stack''':&amp;lt;/span&amp;gt; used to hold successive system priority ceiling values on a LIFO basis, initialized to hold the value 255 (lowest priority).&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS this is a byte array with up to 256 entries (64 words), depending on the number of tasks in an application.&lt;br /&gt;
 Note: should not be confused with the system stack.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''system state variable''':&amp;lt;/span&amp;gt; this is updated by OCEOS when certain error conditions have been detected.&amp;lt;br&amp;gt;&lt;br /&gt;
 When OCEOS does so it may also call a user defined problem handling function that can access this variable, the system log, and timing and other information about tasks, etc. in deciding the action to take.&lt;br /&gt;
 This variable can be accessed by the ASW at any time and can be reset by the application. The variable is reset initially by oceos_init.&lt;br /&gt;
 A copy of this variable is also maintained by OCEOS, this copy is intended to provide a long term record of any problems that have occurred and can be reset and checked by the ASW.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''task''':&amp;lt;/span&amp;gt; the ASW involves a number of relatively independent tasks and also interrupt handling routines.&amp;lt;br&amp;gt;&lt;br /&gt;
 Each task has a principal function that is called to start job execution, and an optional termination function that can be used to terminate task execution in an orderly way if a task has to be aborted.&lt;br /&gt;
 Each task has a fixed priority and fixed pre-emption threshold and a fixed limit to the number of its jobs that can be pending or active simultaneously.&lt;br /&gt;
 The fixed task pre-emption threshold facilitates avoiding context switch overheads for task with very short execution times, and enables task pre-emption be restricted to tasks with significantly higher priorities if desired.&lt;br /&gt;
 OCEOS can be asked to start a task (create a job) before a previous execution of the task has completed, or even begun. A pointer is passed with a task start request that can be used to select the structure processed by a job. &lt;br /&gt;
 Please refer to ‘task job’.&lt;br /&gt;
 A task can be enabled or disabled, in the disabled state attempts to put it into execution fail but are logged.&lt;br /&gt;
 Data stored for each task includes number of times executed, maximum number of current execution instances, maximum number of times pre-empted, minimum time between start requests, maximum activation wait time, maximum execution time and maximum time from start request to completion. This data is updated each time one of the task’s jobs completes.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''task chaining''':&amp;lt;/span&amp;gt; a task can cause another task to start, optionally after a specified time.&amp;lt;br&amp;gt;&lt;br /&gt;
 When a task starts another task it may be pre-empted by the new task.&lt;br /&gt;
 A task can cause itself to restart, but should always choose an appropriate time delay before the restart occurs to ensure lower priority tasks are not locked out.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''task job''':&amp;lt;/span&amp;gt; a request to start a task or the resulting execution instance of the task.&amp;lt;br&amp;gt;&lt;br /&gt;
 A task start request can occur before a job created by a previous request has completed execution, or even begun execution, so a task can have a number of jobs waiting to begin execution.&lt;br /&gt;
 The maximum allowed number of jobs for a task is specified when the task is created.&lt;br /&gt;
 A request to start a task is accompanied by a pointer which is passed to the resulting job allowing different jobs of the same task act on different data.&lt;br /&gt;
 All jobs must complete in finite time with the exception of the idle job.&lt;br /&gt;
 Space to record each job’s information is set aside in the dynamic area by oceos_start.  A job is ‘free’ if its space is not in use, ‘pending’ if it has not yet started execution, ‘active’ if it has started execution.&lt;br /&gt;
 Only pending jobs are placed on pending jobs lists of semaphores or data queues or on the timed actions queue. Active jobs can be pre-empted by higher priority jobs but otherwise run to completion and are never on pending jobs  lists or on the timed actions queue.&lt;br /&gt;
 Data stored for each job includes origin, creation time, activation time, execution time, time to completion, and number of pre-emptions. This job data is used to update the task data when a job terminates.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''task jobs limit''':&amp;lt;/span&amp;gt; this integer is the maximum number of a task’s jobs that can be current, i.e. pending or active at the same time.&amp;lt;br&amp;gt;&lt;br /&gt;
 It is set when the task is created in the range 1 to 15. It should be set to 2 or more unless it is certain that a task start request cannot occur while a task job is already active or pending.&lt;br /&gt;
 N.B. An attempt to create more than this number of current jobs will fail with an error status  being returned, a log entry being made, and the system state variable being updated.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''task pre-emption threshold''':&amp;lt;/span&amp;gt; a task’s pre-emption threshold restricts the tasks that can pre-empt it to those with higher priority than this threshold.&amp;lt;br&amp;gt;&lt;br /&gt;
 A task’s pre-emption threshold is fixed and set when the task is created. It is never lower priority than the task’s priority.&lt;br /&gt;
 A high threshold can be used to prevent pre-emption and avoid context switch overheads for tasks with short run times.&lt;br /&gt;
 A threshold can also be used to allow only the highest priority tasks pre-empt a task while dis-allowing pre-emption by some higher priority tasks.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''task priority''':&amp;lt;/span&amp;gt; a measure of the urgency associated with executing a task’s instructions.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS task priorities are integers in the range 1 (highest task priority) to 254 (lowest task priority) and are fixed when a task is created. More than one task can have the same priority.&lt;br /&gt;
 If a task does not terminate (e.g. the idle task) it must have the lowest task priority to avoid locking out lower priority tasks, and should be the only task with that priority.&lt;br /&gt;
 Tasks with the same priority are executed in FIFO order. Time-slicing or pre-emption between tasks of the same priority does not occur in OCEOS.&lt;br /&gt;
 Please refer also to ‘priority’.&lt;br /&gt;
 N.B. Selecting appropriate priorities for tasks is a key responsibility of the application developer.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''task start''':&amp;lt;/span&amp;gt; create a job, put this job on the ready queue, and call the scheduler after allowing any interrupt nesting present to unwind.&amp;lt;br&amp;gt;&lt;br /&gt;
 If the task has higher priority than the current system priority ceiling the scheduler will pre-empt the current active job and place the new job into execution.&lt;br /&gt;
 In OCEOS after a job is created it remains in a ‘pending’ state until it is first put into execution on the processor, becoming ‘active’ once it has started execution.&lt;br /&gt;
 N.B. If the number of current jobs for this task is already at this task’s jobs limit, a new job will not be created and an error will be reported.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''task state''':&amp;lt;/span&amp;gt; in OCEOS a task has two states, enabled and disabled.&amp;lt;br&amp;gt;&lt;br /&gt;
 OCEOS provides directives to switch a task between states. A task start request only creates a job if the task is enabled.&lt;br /&gt;
 Disabling a task terminates all pending jobs of that task. A task can only be re-enabled once a previous disabling has completed.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''terminate''':&amp;lt;/span&amp;gt; when a job finishes execution it is said to terminate.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS every job except perhaps the idle job terminates after a finite execution time. A job usually terminates itself by exiting its principal function or by calling its termination function.&lt;br /&gt;
 In OCEOS an active job automatically terminates and becomes a pending job on the pending jobs list of a counting semaphore or data queue and/or on the timed actions queue if nothing is available when accessing the semaphore or  data queue and the restart option has been chosen. The job restarts when the semaphore is signalled or queue written, or after a timeout.&lt;br /&gt;
 OCEOS terminates all a task’s pending jobs when it disables a task.&lt;br /&gt;
 On job termination OCEOS updates task parameters such as maximum time to completion and maximum number of pre-emptions.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''timed actions queue''':&amp;lt;/span&amp;gt; a priority queue of pending actions and their associated starts times, with queue priority based on time.&amp;lt;br&amp;gt;&lt;br /&gt;
 It is linked to a timer which is set to interrupt at the time of the first action on the priority queue.&lt;br /&gt;
 After the timed actions have been carried out the timer is reset to interrupt at the start time of the earliest remaining action.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''timed action''':&amp;lt;/span&amp;gt; an action to be done at a specified time involving either transferring a pending job to the ready queue or outputting a value to an address.&amp;lt;br&amp;gt;&lt;br /&gt;
 Involves specifying a forward time tolerance and a backward time tolerance. When a timed action occurs this action and other actions whose forward timing tolerances include the current time are carried out. The backward tolerance allows the action be performed if the current time is later than the requested time by no more than this amount. If set to zero late actions are not performed.&lt;br /&gt;
 All late actions are logged and the system state variable updated.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''trap''':&amp;lt;/span&amp;gt; causes a transfer of control to an address associated with the trap’s identity number.&amp;lt;br&amp;gt;&lt;br /&gt;
 There are three main types of trap. Exceptions are generated by the CPU itself as a result of some exceptional condition such as divide by zero. Software traps are generated by special software trap instructions that give the trap number. Interrupts are caused by external devices usually via an interrupt controller.&lt;br /&gt;
 N.B. Traps should be disabled for the minimum time possible to avoid missing interrupts or delaying the response to them.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''trap handler''':&amp;lt;/span&amp;gt; code that takes the steps immediately necessary to deal with a trap (including interrupts).&amp;lt;br&amp;gt;&lt;br /&gt;
 This code may request OCEOS to start a task, if for an interrupt this code typically resets the cause of the interrupt.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''trap vector table''':&amp;lt;/span&amp;gt; traps (including interrupts) use their identity number to vector to a location in this table which determines the handler code to use.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''user mode''':&amp;lt;/span&amp;gt; code running in user mode must delegate most access to hardware to kernel mode software, typically using a software trap or traps.&amp;lt;br&amp;gt;&lt;br /&gt;
 This mode is often not used in embedded software where the application code typically requires direct access to the hardware.&lt;br /&gt;
 N.B. In OCEOS application code is expected to run in kernel mode not in user mode.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''wait''':&amp;lt;/span&amp;gt; in OCEOS refers to a type of directive used to attempt to lock a mutex or to decrement a counting semaphore.&amp;lt;br&amp;gt;&lt;br /&gt;
 OCEOS does not provide a wait(event) directive, a similar capability can be provided by an interrupt caused by an event signaling a counting semaphore.&lt;br /&gt;
 Please refer to ‘mutex’ and ‘counting semaphore’.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''waiting''':&amp;lt;/span&amp;gt; a state in which a task/job has commenced execution but is not able to continue and must wait for a resource, usually retaining its current stack frame and other context and &lt;br /&gt;
 allowing lower priority tasks/jobs run. In OCEOS this state cannot occur.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS waiting is done only by a pending job, i.e. a job that has not yet started execution and so has no current stack frame, such jobs are described as ‘pending’ rather than ‘waiting’. An active job, i.e. a job that has &lt;br /&gt;
 commenced execution, may be pre-empted by a higher priority job and have to wait to regain the CPU until a higher priority task finishes, but never is delayed by anything except termination of a higher priority job or the ending of an interrupt handling routine.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''warning''':&amp;lt;/span&amp;gt; an OCEOS action that indicates execution was not normal.&amp;lt;br&amp;gt;&lt;br /&gt;
 OCEOS provides different warnings, including returned status codes, system log entries, system state updates, calls to a user defined function, and in the worst case exit from OCEOS.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''watchdog timer''':&amp;lt;/span&amp;gt; a timer connected to the processor reset input so that a system reset will be caused if the timer times out.&amp;lt;br&amp;gt;&lt;br /&gt;
 Usually the lowest priority task has responsibility for resetting the timer before this happens. The timeout interval is chosen so that all higher priority tasks will have completed within the interval thus allowing return to the lowest priority task that then resets the timer. Protects against system lockups due to infinite loops and transient hardware problems.&lt;br /&gt;
 N.B. Creation and management of a watchdog timer is the responsibility of the ASW.&lt;br /&gt;
&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1468</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1468"/>
		<updated>2022-03-31T16:32:43Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 '''Documentation'''/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 '''Examples'''/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 '''include'''/                             // OCEOS header files&lt;br /&gt;
 '''OCEOS_GCC_LIB'''/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Normal operations&amp;lt;/span&amp;gt;====&lt;br /&gt;
The scheduling is started after calling [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The main structure of application flow is described below:&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] - Initialize fixed data and start system time and log&lt;br /&gt;
# Create:&lt;br /&gt;
#* [[OCEOS/oceos kernel/task#oceos_task_create()|oceos_task_create()]] - Create task, setting priority, no of jobs, ..etc.&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/mutex#oceos_mutex_create()|oceos_mutex_create()]] - Create mutexes if require&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/dataq#oceos_dataq_create()|oceos_dataq_create()]] - Create data queues if require&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/semaphore#oceos_sem_create()|oceos_sem_create()]] - Create semaphores if require&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init_finish()|oceos_init_finish()]] - Initialize dynamic data area&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] - Start the scheduler and pass control to first task&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
It is mandatory to create the number of tasks, mutexes, semaphores, and data queues declared in oceos_config.h otherwise oceos_init_finish() will return an error.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OCEOS configuration parameters are shown below. In provided demo projects these are ''oceos_config.h'' and ''oceos_config.c''. More information can be found by clicking on the link for parameter that is of interest.&lt;br /&gt;
&lt;br /&gt;
 // ''1: Includes OCEOS main header file''&lt;br /&gt;
 #include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''2: Number of Log entries.''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|NUMBER_OF_LOG_ENTRIES]]                   16 // ''16 to 1024, default 64''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''3: Number of tasks''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_TASKS]]                         3  // 1 to 255&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);''&lt;br /&gt;
 //    ''Defaults to number of tasks, as each task should have aa least one job;''&lt;br /&gt;
 //    ''If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_READYQ_ENTRIES]]                10&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''5: Number of Mutexes''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/mutex#Mutex_Configuration|NUMBER_OF_MUTEXES]]                       2  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''6: Number of Semaphores''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/semaphore#Semaphore_Configuration|NUMBER_OF_SEMAPHORES]]                    0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''7: Number of Data Qs''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/dataq#Data_Queue_Configuration|NUMBER_OF_DATAQS]]                        0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''8: LOG data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|LOG_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''9: FIXED data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|FIXED_DATA_ARRAY_SIZE_U32S]]              0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''10: DYNAMIC data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|DYN_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''11: Timed Actions''&lt;br /&gt;
 #define [[OCEOS/oceos_timed_actions#Timed_Actions_Configuration|NUMBER_OF_ACTION_ENTRIES]]                0  // ''User-modify field''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''12: Log entries base 2''&lt;br /&gt;
 #define [[OCEOS/oceos_profiling#Configuration|CS_LOG_DEF_ENTRIES_BASE2]]                0&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''13: OCEOS stack start Address''&lt;br /&gt;
 #define OCEOS_STACK_START_ADDRESS               0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''14: OCEOS stack end address''&lt;br /&gt;
 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
&lt;br /&gt;
''application_init()'' function shown below creates OCEOS configuration struct and sets configuration parameter that passed to [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * Not Used for ARM. Always Nested&lt;br /&gt;
     */&lt;br /&gt;
    app_config.interrupt_nesting_enabled     = TRUE;                          // Nesting Enabled&lt;br /&gt;
#endif&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * ARM SysTick is used for System Time&lt;br /&gt;
     */&lt;br /&gt;
    app_config.sys_time_timer_index          = SYS_TIME_TIMER_INDEX;          // 0 =&amp;gt; invalid index&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    // System time is used by timed actions, semaphores with timeout, dataqs with timeout, logging and profiling.&lt;br /&gt;
    // If all of above are not required then system time can be disabled. The system will not be interrupted by SysTick while CPU in sleep mode,&lt;br /&gt;
    //but it is not the case for SPARC targets,&lt;br /&gt;
    // as system time implemented by chaining two timers without interrupting.&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all ARM_BUILD=1 FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 4 – Timer interrupt starts task&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- =&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other RTOS --&amp;gt;&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1467</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1467"/>
		<updated>2022-03-31T16:30:19Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* Drivers Porting Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 '''Documentation'''/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 '''Examples'''/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 '''include'''/                             // OCEOS header files&lt;br /&gt;
 '''OCEOS_GCC_LIB'''/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Normal operations&amp;lt;/span&amp;gt;====&lt;br /&gt;
The scheduling is started after calling [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The main structure of application flow is described below:&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] - Initialize fixed data and start system time and log&lt;br /&gt;
# Create:&lt;br /&gt;
#* [[OCEOS/oceos kernel/task#oceos_task_create()|oceos_task_create()]] - Create task, setting priority, no of jobs, ..etc.&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/mutex#oceos_mutex_create()|oceos_mutex_create()]] - Create mutexes if require&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/dataq#oceos_dataq_create()|oceos_dataq_create()]] - Create data queues if require&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/semaphore#oceos_sem_create()|oceos_sem_create()]] - Create semaphores if require&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init_finish()|oceos_init_finish()]] - Initialize dynamic data area&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] - Start the scheduler and pass control to first task&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
It is mandatory to create the number of tasks, mutexes, semaphores, and data queues declared in oceos_config.h otherwise oceos_init_finish() will return an error.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OCEOS configuration parameters are shown below. In provided demo projects these are ''oceos_config.h'' and ''oceos_config.c''. More information can be found by clicking on the link for parameter that is of interest.&lt;br /&gt;
&lt;br /&gt;
 // ''1: Includes OCEOS main header file''&lt;br /&gt;
 #include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''2: Number of Log entries.''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|NUMBER_OF_LOG_ENTRIES]]                   16 // ''16 to 1024, default 64''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''3: Number of tasks''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_TASKS]]                         3  // 1 to 255&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);''&lt;br /&gt;
 //    ''Defaults to number of tasks, as each task should have aa least one job;''&lt;br /&gt;
 //    ''If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_READYQ_ENTRIES]]                10&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''5: Number of Mutexes''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/mutex#Mutex_Configuration|NUMBER_OF_MUTEXES]]                       2  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''6: Number of Semaphores''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/semaphore#Semaphore_Configuration|NUMBER_OF_SEMAPHORES]]                    0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''7: Number of Data Qs''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/dataq#Data_Queue_Configuration|NUMBER_OF_DATAQS]]                        0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''8: LOG data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|LOG_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''9: FIXED data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|FIXED_DATA_ARRAY_SIZE_U32S]]              0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''10: DYNAMIC data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|DYN_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''11: Timed Actions''&lt;br /&gt;
 #define [[OCEOS/oceos_timed_actions#Timed_Actions_Configuration|NUMBER_OF_ACTION_ENTRIES]]                0  // ''User-modify field''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''12: Log entries base 2''&lt;br /&gt;
 #define [[OCEOS/oceos_profiling#Configuration|CS_LOG_DEF_ENTRIES_BASE2]]                0&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''13: OCEOS stack start Address''&lt;br /&gt;
 #define OCEOS_STACK_START_ADDRESS               0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''14: OCEOS stack end address''&lt;br /&gt;
 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
&lt;br /&gt;
''application_init()'' function shown below creates OCEOS configuration struct and sets configuration parameter that passed to [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * Not Used for ARM. Always Nested&lt;br /&gt;
     */&lt;br /&gt;
    app_config.interrupt_nesting_enabled     = TRUE;                          // Nesting Enabled&lt;br /&gt;
#endif&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * ARM SysTick is used for System Time&lt;br /&gt;
     */&lt;br /&gt;
    app_config.sys_time_timer_index          = SYS_TIME_TIMER_INDEX;          // 0 =&amp;gt; invalid index&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    // System time is used by timed actions, semaphores with timeout, dataqs with timeout, logging and profiling.&lt;br /&gt;
    // If all of above are not required then system time can be disabled. The system will not be interrupted by SysTick while CPU in sleep mode,&lt;br /&gt;
    //but it is not the case for SPARC targets,&lt;br /&gt;
    // as system time implemented by chaining two timers without interrupting.&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all ARM_BUILD=1 FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 4 – Timer interrupt starts task&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;-- =&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other RTOS !--&amp;gt;&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1466</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1466"/>
		<updated>2022-03-31T16:26:21Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 '''Documentation'''/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 '''Examples'''/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 '''include'''/                             // OCEOS header files&lt;br /&gt;
 '''OCEOS_GCC_LIB'''/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Normal operations&amp;lt;/span&amp;gt;====&lt;br /&gt;
The scheduling is started after calling [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The main structure of application flow is described below:&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] - Initialize fixed data and start system time and log&lt;br /&gt;
# Create:&lt;br /&gt;
#* [[OCEOS/oceos kernel/task#oceos_task_create()|oceos_task_create()]] - Create task, setting priority, no of jobs, ..etc.&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/mutex#oceos_mutex_create()|oceos_mutex_create()]] - Create mutexes if require&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/dataq#oceos_dataq_create()|oceos_dataq_create()]] - Create data queues if require&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/semaphore#oceos_sem_create()|oceos_sem_create()]] - Create semaphores if require&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init_finish()|oceos_init_finish()]] - Initialize dynamic data area&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] - Start the scheduler and pass control to first task&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
It is mandatory to create the number of tasks, mutexes, semaphores, and data queues declared in oceos_config.h otherwise oceos_init_finish() will return an error.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OCEOS configuration parameters are shown below. In provided demo projects these are ''oceos_config.h'' and ''oceos_config.c''. More information can be found by clicking on the link for parameter that is of interest.&lt;br /&gt;
&lt;br /&gt;
 // ''1: Includes OCEOS main header file''&lt;br /&gt;
 #include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''2: Number of Log entries.''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|NUMBER_OF_LOG_ENTRIES]]                   16 // ''16 to 1024, default 64''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''3: Number of tasks''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_TASKS]]                         3  // 1 to 255&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);''&lt;br /&gt;
 //    ''Defaults to number of tasks, as each task should have aa least one job;''&lt;br /&gt;
 //    ''If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_READYQ_ENTRIES]]                10&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''5: Number of Mutexes''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/mutex#Mutex_Configuration|NUMBER_OF_MUTEXES]]                       2  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''6: Number of Semaphores''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/semaphore#Semaphore_Configuration|NUMBER_OF_SEMAPHORES]]                    0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''7: Number of Data Qs''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/dataq#Data_Queue_Configuration|NUMBER_OF_DATAQS]]                        0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''8: LOG data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|LOG_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''9: FIXED data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|FIXED_DATA_ARRAY_SIZE_U32S]]              0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''10: DYNAMIC data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|DYN_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''11: Timed Actions''&lt;br /&gt;
 #define [[OCEOS/oceos_timed_actions#Timed_Actions_Configuration|NUMBER_OF_ACTION_ENTRIES]]                0  // ''User-modify field''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''12: Log entries base 2''&lt;br /&gt;
 #define [[OCEOS/oceos_profiling#Configuration|CS_LOG_DEF_ENTRIES_BASE2]]                0&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''13: OCEOS stack start Address''&lt;br /&gt;
 #define OCEOS_STACK_START_ADDRESS               0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''14: OCEOS stack end address''&lt;br /&gt;
 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
&lt;br /&gt;
''application_init()'' function shown below creates OCEOS configuration struct and sets configuration parameter that passed to [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * Not Used for ARM. Always Nested&lt;br /&gt;
     */&lt;br /&gt;
    app_config.interrupt_nesting_enabled     = TRUE;                          // Nesting Enabled&lt;br /&gt;
#endif&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * ARM SysTick is used for System Time&lt;br /&gt;
     */&lt;br /&gt;
    app_config.sys_time_timer_index          = SYS_TIME_TIMER_INDEX;          // 0 =&amp;gt; invalid index&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    // System time is used by timed actions, semaphores with timeout, dataqs with timeout, logging and profiling.&lt;br /&gt;
    // If all of above are not required then system time can be disabled. The system will not be interrupted by SysTick while CPU in sleep mode,&lt;br /&gt;
    //but it is not the case for SPARC targets,&lt;br /&gt;
    // as system time implemented by chaining two timers without interrupting.&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all ARM_BUILD=1 FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 4 – Timer interrupt starts task&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1465</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1465"/>
		<updated>2022-03-31T15:47:53Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* Building the example application */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Normal operations&amp;lt;/span&amp;gt;====&lt;br /&gt;
The scheduling is started after calling [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The main structure of application flow is described below:&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] - Initialize fixed data and start system time and log&lt;br /&gt;
# Create:&lt;br /&gt;
#* [[OCEOS/oceos kernel/task#oceos_task_create()|oceos_task_create()]] - Create task, setting priority, no of jobs, ..etc.&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/mutex#oceos_mutex_create()|oceos_mutex_create()]] - Create mutexes if require&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/dataq#oceos_dataq_create()|oceos_dataq_create()]] - Create data queues if require&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/semaphore#oceos_sem_create()|oceos_sem_create()]] - Create semaphores if require&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init_finish()|oceos_init_finish()]] - Initialize dynamic data area&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] - Start the scheduler and pass control to first task&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
It is mandatory to create the number of tasks, mutexes, semaphores, and data queues declared in oceos_config.h otherwise oceos_init_finish() will return an error.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OCEOS configuration parameters are shown below. In provided demo projects these are ''oceos_config.h'' and ''oceos_config.c''. More information can be found by clicking on the link for parameter that is of interest.&lt;br /&gt;
&lt;br /&gt;
 // ''1: Includes OCEOS main header file''&lt;br /&gt;
 #include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''2: Number of Log entries.''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|NUMBER_OF_LOG_ENTRIES]]                   16 // ''16 to 1024, default 64''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''3: Number of tasks''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_TASKS]]                         3  // 1 to 255&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);''&lt;br /&gt;
 //    ''Defaults to number of tasks, as each task should have aa least one job;''&lt;br /&gt;
 //    ''If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_READYQ_ENTRIES]]                10&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''5: Number of Mutexes''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/mutex#Mutex_Configuration|NUMBER_OF_MUTEXES]]                       2  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''6: Number of Semaphores''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/semaphore#Semaphore_Configuration|NUMBER_OF_SEMAPHORES]]                    0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''7: Number of Data Qs''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/dataq#Data_Queue_Configuration|NUMBER_OF_DATAQS]]                        0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''8: LOG data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|LOG_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''9: FIXED data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|FIXED_DATA_ARRAY_SIZE_U32S]]              0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''10: DYNAMIC data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|DYN_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''11: Timed Actions''&lt;br /&gt;
 #define [[OCEOS/oceos_timed_actions#Timed_Actions_Configuration|NUMBER_OF_ACTION_ENTRIES]]                0  // ''User-modify field''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''12: Log entries base 2''&lt;br /&gt;
 #define [[OCEOS/oceos_profiling#Configuration|CS_LOG_DEF_ENTRIES_BASE2]]                0&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''13: OCEOS stack start Address''&lt;br /&gt;
 #define OCEOS_STACK_START_ADDRESS               0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''14: OCEOS stack end address''&lt;br /&gt;
 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
&lt;br /&gt;
''application_init()'' function shown below creates OCEOS configuration struct and sets configuration parameter that passed to [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * Not Used for ARM. Always Nested&lt;br /&gt;
     */&lt;br /&gt;
    app_config.interrupt_nesting_enabled     = TRUE;                          // Nesting Enabled&lt;br /&gt;
#endif&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * ARM SysTick is used for System Time&lt;br /&gt;
     */&lt;br /&gt;
    app_config.sys_time_timer_index          = SYS_TIME_TIMER_INDEX;          // 0 =&amp;gt; invalid index&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    // System time is used by timed actions, semaphores with timeout, dataqs with timeout, logging and profiling.&lt;br /&gt;
    // If all of above are not required then system time can be disabled. The system will not be interrupted by SysTick while CPU in sleep mode,&lt;br /&gt;
    //but it is not the case for SPARC targets,&lt;br /&gt;
    // as system time implemented by chaining two timers without interrupting.&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 '''Documentation'''/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 '''Examples'''/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 '''include'''/                             // OCEOS header files&lt;br /&gt;
 '''OCEOS_GCC_LIB'''/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all ARM_BUILD=1 FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 4 – Timer interrupt starts task&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1464</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1464"/>
		<updated>2022-03-31T15:41:02Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* OCEOS Demo Tutorials */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Normal operations&amp;lt;/span&amp;gt;====&lt;br /&gt;
The scheduling is started after calling [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The main structure of application flow is described below:&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] - Initialize fixed data and start system time and log&lt;br /&gt;
# Create:&lt;br /&gt;
#* [[OCEOS/oceos kernel/task#oceos_task_create()|oceos_task_create()]] - Create task, setting priority, no of jobs, ..etc.&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/mutex#oceos_mutex_create()|oceos_mutex_create()]] - Create mutexes if require&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/dataq#oceos_dataq_create()|oceos_dataq_create()]] - Create data queues if require&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/semaphore#oceos_sem_create()|oceos_sem_create()]] - Create semaphores if require&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init_finish()|oceos_init_finish()]] - Initialize dynamic data area&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] - Start the scheduler and pass control to first task&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
It is mandatory to create the number of tasks, mutexes, semaphores, and data queues declared in oceos_config.h otherwise oceos_init_finish() will return an error.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OCEOS configuration parameters are shown below. In provided demo projects these are ''oceos_config.h'' and ''oceos_config.c''. More information can be found by clicking on the link for parameter that is of interest.&lt;br /&gt;
&lt;br /&gt;
 // ''1: Includes OCEOS main header file''&lt;br /&gt;
 #include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''2: Number of Log entries.''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|NUMBER_OF_LOG_ENTRIES]]                   16 // ''16 to 1024, default 64''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''3: Number of tasks''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_TASKS]]                         3  // 1 to 255&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);''&lt;br /&gt;
 //    ''Defaults to number of tasks, as each task should have aa least one job;''&lt;br /&gt;
 //    ''If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_READYQ_ENTRIES]]                10&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''5: Number of Mutexes''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/mutex#Mutex_Configuration|NUMBER_OF_MUTEXES]]                       2  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''6: Number of Semaphores''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/semaphore#Semaphore_Configuration|NUMBER_OF_SEMAPHORES]]                    0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''7: Number of Data Qs''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/dataq#Data_Queue_Configuration|NUMBER_OF_DATAQS]]                        0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''8: LOG data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|LOG_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''9: FIXED data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|FIXED_DATA_ARRAY_SIZE_U32S]]              0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''10: DYNAMIC data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|DYN_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''11: Timed Actions''&lt;br /&gt;
 #define [[OCEOS/oceos_timed_actions#Timed_Actions_Configuration|NUMBER_OF_ACTION_ENTRIES]]                0  // ''User-modify field''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''12: Log entries base 2''&lt;br /&gt;
 #define [[OCEOS/oceos_profiling#Configuration|CS_LOG_DEF_ENTRIES_BASE2]]                0&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''13: OCEOS stack start Address''&lt;br /&gt;
 #define OCEOS_STACK_START_ADDRESS               0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''14: OCEOS stack end address''&lt;br /&gt;
 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
&lt;br /&gt;
''application_init()'' function shown below creates OCEOS configuration struct and sets configuration parameter that passed to [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * Not Used for ARM. Always Nested&lt;br /&gt;
     */&lt;br /&gt;
    app_config.interrupt_nesting_enabled     = TRUE;                          // Nesting Enabled&lt;br /&gt;
#endif&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * ARM SysTick is used for System Time&lt;br /&gt;
     */&lt;br /&gt;
    app_config.sys_time_timer_index          = SYS_TIME_TIMER_INDEX;          // 0 =&amp;gt; invalid index&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    // System time is used by timed actions, semaphores with timeout, dataqs with timeout, logging and profiling.&lt;br /&gt;
    // If all of above are not required then system time can be disabled. The system will not be interrupted by SysTick while CPU in sleep mode,&lt;br /&gt;
    //but it is not the case for SPARC targets,&lt;br /&gt;
    // as system time implemented by chaining two timers without interrupting.&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 '''Documentation'''/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 '''Examples'''/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 '''include'''/                             // OCEOS header files&lt;br /&gt;
 '''OCEOS_GCC_LIB'''/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 4 – Timer interrupt starts task&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        SPARC and ARM Microcontrollers&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1463</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1463"/>
		<updated>2022-03-31T15:38:49Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* OCEOS Normal operations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Normal operations&amp;lt;/span&amp;gt;====&lt;br /&gt;
The scheduling is started after calling [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The main structure of application flow is described below:&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] - Initialize fixed data and start system time and log&lt;br /&gt;
# Create:&lt;br /&gt;
#* [[OCEOS/oceos kernel/task#oceos_task_create()|oceos_task_create()]] - Create task, setting priority, no of jobs, ..etc.&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/mutex#oceos_mutex_create()|oceos_mutex_create()]] - Create mutexes if require&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/dataq#oceos_dataq_create()|oceos_dataq_create()]] - Create data queues if require&lt;br /&gt;
#* [[OCEOS/oceos inter-task communication/semaphore#oceos_sem_create()|oceos_sem_create()]] - Create semaphores if require&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init_finish()|oceos_init_finish()]] - Initialize dynamic data area&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] - Start the scheduler and pass control to first task&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
It is mandatory to create the number of tasks, mutexes, semaphores, and data queues declared in oceos_config.h otherwise oceos_init_finish() will return an error.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OCEOS configuration parameters are shown below. In provided demo projects these are ''oceos_config.h'' and ''oceos_config.c''. More information can be found by clicking on the link for parameter that is of interest.&lt;br /&gt;
&lt;br /&gt;
 // ''1: Includes OCEOS main header file''&lt;br /&gt;
 #include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''2: Number of Log entries.''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|NUMBER_OF_LOG_ENTRIES]]                   16 // ''16 to 1024, default 64''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''3: Number of tasks''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_TASKS]]                         3  // 1 to 255&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);''&lt;br /&gt;
 //    ''Defaults to number of tasks, as each task should have aa least one job;''&lt;br /&gt;
 //    ''If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_READYQ_ENTRIES]]                10&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''5: Number of Mutexes''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/mutex#Mutex_Configuration|NUMBER_OF_MUTEXES]]                       2  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''6: Number of Semaphores''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/semaphore#Semaphore_Configuration|NUMBER_OF_SEMAPHORES]]                    0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''7: Number of Data Qs''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/dataq#Data_Queue_Configuration|NUMBER_OF_DATAQS]]                        0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''8: LOG data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|LOG_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''9: FIXED data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|FIXED_DATA_ARRAY_SIZE_U32S]]              0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''10: DYNAMIC data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|DYN_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''11: Timed Actions''&lt;br /&gt;
 #define [[OCEOS/oceos_timed_actions#Timed_Actions_Configuration|NUMBER_OF_ACTION_ENTRIES]]                0  // ''User-modify field''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''12: Log entries base 2''&lt;br /&gt;
 #define [[OCEOS/oceos_profiling#Configuration|CS_LOG_DEF_ENTRIES_BASE2]]                0&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''13: OCEOS stack start Address''&lt;br /&gt;
 #define OCEOS_STACK_START_ADDRESS               0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''14: OCEOS stack end address''&lt;br /&gt;
 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
&lt;br /&gt;
''application_init()'' function shown below creates OCEOS configuration struct and sets configuration parameter that passed to [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * Not Used for ARM. Always Nested&lt;br /&gt;
     */&lt;br /&gt;
    app_config.interrupt_nesting_enabled     = TRUE;                          // Nesting Enabled&lt;br /&gt;
#endif&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * ARM SysTick is used for System Time&lt;br /&gt;
     */&lt;br /&gt;
    app_config.sys_time_timer_index          = SYS_TIME_TIMER_INDEX;          // 0 =&amp;gt; invalid index&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    // System time is used by timed actions, semaphores with timeout, dataqs with timeout, logging and profiling.&lt;br /&gt;
    // If all of above are not required then system time can be disabled. The system will not be interrupted by SysTick while CPU in sleep mode,&lt;br /&gt;
    //but it is not the case for SPARC targets,&lt;br /&gt;
    // as system time implemented by chaining two timers without interrupting.&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 '''Documentation'''/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 '''Examples'''/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 '''include'''/                             // OCEOS header files&lt;br /&gt;
 '''OCEOS_GCC_LIB'''/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 4 – Timer interrupt starts task&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1462</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1462"/>
		<updated>2022-03-31T15:36:59Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* OCEOS Normal operations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Normal operations&amp;lt;/span&amp;gt;====&lt;br /&gt;
The scheduling is started after calling [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The main structure of application flow is described below:&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] - Initialize fixed data and start system time and log&lt;br /&gt;
# Create:&lt;br /&gt;
#.## [[OCEOS/oceos kernel/task#oceos_task_create()|oceos_task_create()]] - Create task, setting priority, no of jobs, ..etc.&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/mutex#oceos_mutex_create()|oceos_mutex_create()]] - Create mutexes if require&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/dataq#oceos_dataq_create()|oceos_dataq_create()]] - Create data queues if require&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/semaphore#oceos_sem_create()|oceos_sem_create()]] - Create semaphores if require&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init_finish()|oceos_init_finish()]] - Initialize dynamic data area&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] - Start the scheduler and pass control to first task&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
It is mandatory to create the number of tasks, mutexes, semaphores, and data queues declared in oceos_config.h otherwise oceos_init_finish() will return an error.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OCEOS configuration parameters are shown below. In provided demo projects these are ''oceos_config.h'' and ''oceos_config.c''. More information can be found by clicking on the link for parameter that is of interest.&lt;br /&gt;
&lt;br /&gt;
 // ''1: Includes OCEOS main header file''&lt;br /&gt;
 #include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''2: Number of Log entries.''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|NUMBER_OF_LOG_ENTRIES]]                   16 // ''16 to 1024, default 64''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''3: Number of tasks''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_TASKS]]                         3  // 1 to 255&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);''&lt;br /&gt;
 //    ''Defaults to number of tasks, as each task should have aa least one job;''&lt;br /&gt;
 //    ''If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_READYQ_ENTRIES]]                10&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''5: Number of Mutexes''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/mutex#Mutex_Configuration|NUMBER_OF_MUTEXES]]                       2  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''6: Number of Semaphores''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/semaphore#Semaphore_Configuration|NUMBER_OF_SEMAPHORES]]                    0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''7: Number of Data Qs''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/dataq#Data_Queue_Configuration|NUMBER_OF_DATAQS]]                        0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''8: LOG data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|LOG_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''9: FIXED data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|FIXED_DATA_ARRAY_SIZE_U32S]]              0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''10: DYNAMIC data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|DYN_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''11: Timed Actions''&lt;br /&gt;
 #define [[OCEOS/oceos_timed_actions#Timed_Actions_Configuration|NUMBER_OF_ACTION_ENTRIES]]                0  // ''User-modify field''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''12: Log entries base 2''&lt;br /&gt;
 #define [[OCEOS/oceos_profiling#Configuration|CS_LOG_DEF_ENTRIES_BASE2]]                0&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''13: OCEOS stack start Address''&lt;br /&gt;
 #define OCEOS_STACK_START_ADDRESS               0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''14: OCEOS stack end address''&lt;br /&gt;
 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
&lt;br /&gt;
''application_init()'' function shown below creates OCEOS configuration struct and sets configuration parameter that passed to [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * Not Used for ARM. Always Nested&lt;br /&gt;
     */&lt;br /&gt;
    app_config.interrupt_nesting_enabled     = TRUE;                          // Nesting Enabled&lt;br /&gt;
#endif&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * ARM SysTick is used for System Time&lt;br /&gt;
     */&lt;br /&gt;
    app_config.sys_time_timer_index          = SYS_TIME_TIMER_INDEX;          // 0 =&amp;gt; invalid index&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    // System time is used by timed actions, semaphores with timeout, dataqs with timeout, logging and profiling.&lt;br /&gt;
    // If all of above are not required then system time can be disabled. The system will not be interrupted by SysTick while CPU in sleep mode,&lt;br /&gt;
    //but it is not the case for SPARC targets,&lt;br /&gt;
    // as system time implemented by chaining two timers without interrupting.&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 '''Documentation'''/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 '''Examples'''/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 '''include'''/                             // OCEOS header files&lt;br /&gt;
 '''OCEOS_GCC_LIB'''/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 4 – Timer interrupt starts task&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1461</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1461"/>
		<updated>2022-03-31T15:36:24Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* OCEOS Normal operations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Normal operations&amp;lt;/span&amp;gt;====&lt;br /&gt;
The scheduling is started after calling [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The main structure of application flow is described below:&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] - Initialize fixed data and start system time and log&lt;br /&gt;
# Create:&lt;br /&gt;
** [[OCEOS/oceos kernel/task#oceos_task_create()|oceos_task_create()]] - Create task, setting priority, no of jobs, ..etc.&lt;br /&gt;
** [[OCEOS/oceos inter-task communication/mutex#oceos_mutex_create()|oceos_mutex_create()]] - Create mutexes if require&lt;br /&gt;
** [[OCEOS/oceos inter-task communication/dataq#oceos_dataq_create()|oceos_dataq_create()]] - Create data queues if require&lt;br /&gt;
** [[OCEOS/oceos inter-task communication/semaphore#oceos_sem_create()|oceos_sem_create()]] - Create semaphores if require&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init_finish()|oceos_init_finish()]] - Initialize dynamic data area&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] - Start the scheduler and pass control to first task&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
It is mandatory to create the number of tasks, mutexes, semaphores, and data queues declared in oceos_config.h otherwise oceos_init_finish() will return an error.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OCEOS configuration parameters are shown below. In provided demo projects these are ''oceos_config.h'' and ''oceos_config.c''. More information can be found by clicking on the link for parameter that is of interest.&lt;br /&gt;
&lt;br /&gt;
 // ''1: Includes OCEOS main header file''&lt;br /&gt;
 #include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''2: Number of Log entries.''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|NUMBER_OF_LOG_ENTRIES]]                   16 // ''16 to 1024, default 64''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''3: Number of tasks''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_TASKS]]                         3  // 1 to 255&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);''&lt;br /&gt;
 //    ''Defaults to number of tasks, as each task should have aa least one job;''&lt;br /&gt;
 //    ''If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_READYQ_ENTRIES]]                10&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''5: Number of Mutexes''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/mutex#Mutex_Configuration|NUMBER_OF_MUTEXES]]                       2  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''6: Number of Semaphores''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/semaphore#Semaphore_Configuration|NUMBER_OF_SEMAPHORES]]                    0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''7: Number of Data Qs''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/dataq#Data_Queue_Configuration|NUMBER_OF_DATAQS]]                        0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''8: LOG data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|LOG_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''9: FIXED data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|FIXED_DATA_ARRAY_SIZE_U32S]]              0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''10: DYNAMIC data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|DYN_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''11: Timed Actions''&lt;br /&gt;
 #define [[OCEOS/oceos_timed_actions#Timed_Actions_Configuration|NUMBER_OF_ACTION_ENTRIES]]                0  // ''User-modify field''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''12: Log entries base 2''&lt;br /&gt;
 #define [[OCEOS/oceos_profiling#Configuration|CS_LOG_DEF_ENTRIES_BASE2]]                0&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''13: OCEOS stack start Address''&lt;br /&gt;
 #define OCEOS_STACK_START_ADDRESS               0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''14: OCEOS stack end address''&lt;br /&gt;
 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
&lt;br /&gt;
''application_init()'' function shown below creates OCEOS configuration struct and sets configuration parameter that passed to [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * Not Used for ARM. Always Nested&lt;br /&gt;
     */&lt;br /&gt;
    app_config.interrupt_nesting_enabled     = TRUE;                          // Nesting Enabled&lt;br /&gt;
#endif&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * ARM SysTick is used for System Time&lt;br /&gt;
     */&lt;br /&gt;
    app_config.sys_time_timer_index          = SYS_TIME_TIMER_INDEX;          // 0 =&amp;gt; invalid index&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    // System time is used by timed actions, semaphores with timeout, dataqs with timeout, logging and profiling.&lt;br /&gt;
    // If all of above are not required then system time can be disabled. The system will not be interrupted by SysTick while CPU in sleep mode,&lt;br /&gt;
    //but it is not the case for SPARC targets,&lt;br /&gt;
    // as system time implemented by chaining two timers without interrupting.&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 '''Documentation'''/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 '''Examples'''/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 '''include'''/                             // OCEOS header files&lt;br /&gt;
 '''OCEOS_GCC_LIB'''/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 4 – Timer interrupt starts task&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1460</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1460"/>
		<updated>2022-03-31T15:34:46Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* OCEOS Normal operations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Normal operations&amp;lt;/span&amp;gt;====&lt;br /&gt;
The scheduling is started after calling [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The main structure of application flow is described below:&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] - Initialize fixed data and start system time and log&lt;br /&gt;
# Create:&lt;br /&gt;
## [[OCEOS/oceos kernel/task#oceos_task_create()|oceos_task_create()]] - Create task, setting priority, no of jobs, ..etc.&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/mutex#oceos_mutex_create()|oceos_mutex_create()]] - Create mutexes if require&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/dataq#oceos_dataq_create()|oceos_dataq_create()]] - Create data queues if require&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/semaphore#oceos_sem_create()|oceos_sem_create()]] - Create semaphores if require&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init_finish()|oceos_init_finish()]] - Initialize dynamic data area&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] - Start the scheduler and pass control to first task&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
It is mandatory to create the number of tasks, mutexes, semaphores, and data queues declared in oceos_config.h otherwise oceos_init_finish() will return an error.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OCEOS configuration parameters are shown below. In provided demo projects these are ''oceos_config.h'' and ''oceos_config.c''. More information can be found by clicking on the link for parameter that is of interest.&lt;br /&gt;
&lt;br /&gt;
 // ''1: Includes OCEOS main header file''&lt;br /&gt;
 #include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''2: Number of Log entries.''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|NUMBER_OF_LOG_ENTRIES]]                   16 // ''16 to 1024, default 64''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''3: Number of tasks''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_TASKS]]                         3  // 1 to 255&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);''&lt;br /&gt;
 //    ''Defaults to number of tasks, as each task should have aa least one job;''&lt;br /&gt;
 //    ''If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_READYQ_ENTRIES]]                10&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''5: Number of Mutexes''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/mutex#Mutex_Configuration|NUMBER_OF_MUTEXES]]                       2  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''6: Number of Semaphores''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/semaphore#Semaphore_Configuration|NUMBER_OF_SEMAPHORES]]                    0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''7: Number of Data Qs''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/dataq#Data_Queue_Configuration|NUMBER_OF_DATAQS]]                        0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''8: LOG data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|LOG_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''9: FIXED data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|FIXED_DATA_ARRAY_SIZE_U32S]]              0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''10: DYNAMIC data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|DYN_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''11: Timed Actions''&lt;br /&gt;
 #define [[OCEOS/oceos_timed_actions#Timed_Actions_Configuration|NUMBER_OF_ACTION_ENTRIES]]                0  // ''User-modify field''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''12: Log entries base 2''&lt;br /&gt;
 #define [[OCEOS/oceos_profiling#Configuration|CS_LOG_DEF_ENTRIES_BASE2]]                0&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''13: OCEOS stack start Address''&lt;br /&gt;
 #define OCEOS_STACK_START_ADDRESS               0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''14: OCEOS stack end address''&lt;br /&gt;
 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
&lt;br /&gt;
''application_init()'' function shown below creates OCEOS configuration struct and sets configuration parameter that passed to [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * Not Used for ARM. Always Nested&lt;br /&gt;
     */&lt;br /&gt;
    app_config.interrupt_nesting_enabled     = TRUE;                          // Nesting Enabled&lt;br /&gt;
#endif&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * ARM SysTick is used for System Time&lt;br /&gt;
     */&lt;br /&gt;
    app_config.sys_time_timer_index          = SYS_TIME_TIMER_INDEX;          // 0 =&amp;gt; invalid index&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    // System time is used by timed actions, semaphores with timeout, dataqs with timeout, logging and profiling.&lt;br /&gt;
    // If all of above are not required then system time can be disabled. The system will not be interrupted by SysTick while CPU in sleep mode,&lt;br /&gt;
    //but it is not the case for SPARC targets,&lt;br /&gt;
    // as system time implemented by chaining two timers without interrupting.&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 '''Documentation'''/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 '''Examples'''/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 '''include'''/                             // OCEOS header files&lt;br /&gt;
 '''OCEOS_GCC_LIB'''/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 4 – Timer interrupt starts task&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1459</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1459"/>
		<updated>2022-03-31T15:25:50Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Normal operations&amp;lt;/span&amp;gt;====&lt;br /&gt;
The scheduling is started after calling [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The main structure of application flow is described below:&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] - Initialize fixed data and start system time and log&lt;br /&gt;
# Create:&lt;br /&gt;
## [[OCEOS/oceos kernel/task#oceos_task_create()|oceos_task_create()]] - Create task, setting priority, no of jobs, ..etc.&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/mutex#oceos_mutex_create()|oceos_mutex_create()]] - Create mutexes if require&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/dataq#oceos_dataq_create()|oceos_dataq_create()]] - Create data queues if require&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/semaphore#oceos_sem_create()|oceos_sem_create()]] - Create semaphores if require&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init_finish()|oceos_init_finish()]] - Initialize dynamic data area&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] - Start the scheduler and pass control to first task&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
It is mandatory to create the number of tasks, mutexes, semaphores, and data queues declared in oceos_config.h otherwise oceos_init_finish() will return an error.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OCEOS configuration parameters are shown below. In provided demo projects these are ''oceos_config.h'' and ''oceos_config.c''. More information can be found by clicking on the link for parameter that is of interest.&lt;br /&gt;
&lt;br /&gt;
 // ''1: Includes OCEOS main header file''&lt;br /&gt;
 #include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''2: Number of Log entries.''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|NUMBER_OF_LOG_ENTRIES]]                   16 // ''16 to 1024, default 64''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''3: Number of tasks''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_TASKS]]                         3  // 1 to 255&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);''&lt;br /&gt;
 //    ''Defaults to number of tasks, as each task should have aa least one job;''&lt;br /&gt;
 //    ''If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs''&lt;br /&gt;
 #define [[OCEOS/oceos_kernel/task#Task_Configuration|NUMBER_OF_READYQ_ENTRIES]]                10&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''5: Number of Mutexes''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/mutex#Mutex_Configuration|NUMBER_OF_MUTEXES]]                       2  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''6: Number of Semaphores''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/semaphore#Semaphore_Configuration|NUMBER_OF_SEMAPHORES]]                    0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''7: Number of Data Qs''&lt;br /&gt;
 #define [[OCEOS/oceos_inter-task_communication/dataq#Data_Queue_Configuration|NUMBER_OF_DATAQS]]                        0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''8: LOG data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_logging#Logging_Configuration|LOG_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''9: FIXED data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|FIXED_DATA_ARRAY_SIZE_U32S]]              0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''10: DYNAMIC data array size''&lt;br /&gt;
 #define [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|DYN_DATA_ARRAY_SIZE_U32S]]                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''11: Timed Actions''&lt;br /&gt;
 #define [[OCEOS/oceos_timed_actions#Timed_Actions_Configuration|NUMBER_OF_ACTION_ENTRIES]]                0  // ''User-modify field''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''12: Log entries base 2''&lt;br /&gt;
 #define [[OCEOS/oceos_profiling#Configuration|CS_LOG_DEF_ENTRIES_BASE2]]                0&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''13: OCEOS stack start Address''&lt;br /&gt;
 #define OCEOS_STACK_START_ADDRESS               0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''14: OCEOS stack end address''&lt;br /&gt;
 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * Not Used for ARM. Always Nested&lt;br /&gt;
     */&lt;br /&gt;
    app_config.interrupt_nesting_enabled     = TRUE;                          // Nesting Enabled&lt;br /&gt;
#endif&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * ARM SysTick is used for System Time&lt;br /&gt;
     */&lt;br /&gt;
    app_config.sys_time_timer_index          = SYS_TIME_TIMER_INDEX;          // 0 =&amp;gt; invalid index&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    // System time is used by timed actions, semaphores with timeout, dataqs with timeout, logging and profiling.&lt;br /&gt;
    // If all of above are not required then system time can be disabled. The system will not be interrupted by SysTick while CPU in sleep mode,&lt;br /&gt;
    //but it is not the case for SPARC targets,&lt;br /&gt;
    // as system time implemented by chaining two timers without interrupting.&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 '''Documentation'''/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 '''Examples'''/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 '''include'''/                             // OCEOS header files&lt;br /&gt;
 '''OCEOS_GCC_LIB'''/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 4 – Timer interrupt starts task&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1458</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1458"/>
		<updated>2022-03-31T15:19:40Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* OCEOS Normal operations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Normal operations&amp;lt;/span&amp;gt;====&lt;br /&gt;
The scheduling is started after calling [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The main structure of application flow is described below:&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] - Initialize fixed data and start system time and log&lt;br /&gt;
# Create:&lt;br /&gt;
## [[OCEOS/oceos kernel/task#oceos_task_create()|oceos_task_create()]] - Create task, setting priority, no of jobs, ..etc.&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/mutex#oceos_mutex_create()|oceos_mutex_create()]] - Create mutexes if require&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/dataq#oceos_dataq_create()|oceos_dataq_create()]] - Create data queues if require&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/semaphore#oceos_sem_create()|oceos_sem_create()]] - Create semaphores if require&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init_finish()|oceos_init_finish()]] - Initialize dynamic data area&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] - Start the scheduler and pass control to first task&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
It is mandatory to create the number of tasks, mutexes, semaphores, and data queues declared in oceos_config.h otherwise oceos_init_finish() will return an error.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OCEOS configuration parameters are shown below. In provided demo projects these are ''oceos_config.h'' and ''oceos_config.c''. More information can be found by clicking on the link for parameter that is of interest.&lt;br /&gt;
&lt;br /&gt;
 // ''1: Includes OCEOS main header file''&lt;br /&gt;
 #include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''2: Number of Log entries.''&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:##ffbf00&amp;quot;&amp;gt;#define&amp;lt;/span&amp;gt; [[OCEOS/oceos_logging#Logging_Configuration|NUMBER_OF_LOG_ENTRIES]]                   16 ''// 16 to 1024, default 64''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''3: Number of tasks''&lt;br /&gt;
 #define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);''&lt;br /&gt;
 //    ''Defaults to number of tasks, as each task should have aa least one job;''&lt;br /&gt;
 //    ''If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs''&lt;br /&gt;
 #define NUMBER_OF_READYQ_ENTRIES                10&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''5: Number of Mutexes''&lt;br /&gt;
 #define NUMBER_OF_MUTEXES                       2  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''6: Number of Semaphores''&lt;br /&gt;
 #define NUMBER_OF_SEMAPHORES                    0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''7: Number of Data Qs''&lt;br /&gt;
 #define NUMBER_OF_DATAQS                        0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''8: LOG data array size''&lt;br /&gt;
 #define LOG_DATA_ARRAY_SIZE_U32S                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''9: FIXED data array size''&lt;br /&gt;
 #define FIXED_DATA_ARRAY_SIZE_U32S              0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''10: DYNAMIC data array size''&lt;br /&gt;
 #define DYN_DATA_ARRAY_SIZE_U32S                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''11: Timed Actions''&lt;br /&gt;
 #define NUMBER_OF_ACTION_ENTRIES                0  // ''User-modify field''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''12: Log entries base 2''&lt;br /&gt;
 #define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''13: OCEOS stack start Address''&lt;br /&gt;
 #define OCEOS_STACK_START_ADDRESS               0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''14: OCEOS stack end address''&lt;br /&gt;
 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * Not Used for ARM. Always Nested&lt;br /&gt;
     */&lt;br /&gt;
    app_config.interrupt_nesting_enabled     = TRUE;                          // Nesting Enabled&lt;br /&gt;
#endif&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * ARM SysTick is used for System Time&lt;br /&gt;
     */&lt;br /&gt;
    app_config.sys_time_timer_index          = SYS_TIME_TIMER_INDEX;          // 0 =&amp;gt; invalid index&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    // System time is used by timed actions, semaphores with timeout, dataqs with timeout, logging and profiling.&lt;br /&gt;
    // If all of above are not required then system time can be disabled. The system will not be interrupted by SysTick while CPU in sleep mode,&lt;br /&gt;
    //but it is not the case for SPARC targets,&lt;br /&gt;
    // as system time implemented by chaining two timers without interrupting.&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 '''Documentation'''/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 '''Examples'''/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 '''include'''/                             // OCEOS header files&lt;br /&gt;
 '''OCEOS_GCC_LIB'''/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 4 – Timer interrupt starts task&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1457</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1457"/>
		<updated>2022-03-31T15:19:07Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* OCEOS Normal operations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Normal operations&amp;lt;/span&amp;gt;====&lt;br /&gt;
The scheduling is started after calling [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The main structure of application flow is described below:&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] - Initialize fixed data and start system time and log&lt;br /&gt;
# Create:&lt;br /&gt;
## [[OCEOS/oceos kernel/task#oceos_task_create()|oceos_task_create()]] - Create task, setting priority, no of jobs, ..etc.&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/mutex#oceos_mutex_create()|oceos_mutex_create()]] - Create mutexes if require&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/dataq#oceos_dataq_create()|oceos_dataq_create()]] - Create data queues if require&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/semaphore#oceos_sem_create()|oceos_sem_create()]] - Create semaphores if require&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init_finish()|oceos_init_finish()]] - Initialize dynamic data area&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] - Start the scheduler and pass control to first task&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
It is mandatory to create the number of tasks, mutexes, semaphores, and data queues declared in oceos_config.h otherwise oceos_init_finish() will return an error.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OCEOS configuration parameters are shown below. In provided demo projects these are ''oceos_config.h'' and ''oceos_config.c''. More information can be found by clicking on the link for parameter that is of interest.&lt;br /&gt;
&lt;br /&gt;
 // ''1: Includes OCEOS main header file''&lt;br /&gt;
 #include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''2: Number of Log entries.''&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:##ffbf00&amp;quot;&amp;gt;#define  [[OCEOS/oceos_logging#Logging_Configuration|NUMBER_OF_LOG_ENTRIES]]                   16&amp;lt;/span&amp;gt; ''// 16 to 1024, default 64''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''3: Number of tasks''&lt;br /&gt;
 #define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);''&lt;br /&gt;
 //    ''Defaults to number of tasks, as each task should have aa least one job;''&lt;br /&gt;
 //    ''If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs''&lt;br /&gt;
 #define NUMBER_OF_READYQ_ENTRIES                10&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''5: Number of Mutexes''&lt;br /&gt;
 #define NUMBER_OF_MUTEXES                       2  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''6: Number of Semaphores''&lt;br /&gt;
 #define NUMBER_OF_SEMAPHORES                    0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''7: Number of Data Qs''&lt;br /&gt;
 #define NUMBER_OF_DATAQS                        0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''8: LOG data array size''&lt;br /&gt;
 #define LOG_DATA_ARRAY_SIZE_U32S                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''9: FIXED data array size''&lt;br /&gt;
 #define FIXED_DATA_ARRAY_SIZE_U32S              0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''10: DYNAMIC data array size''&lt;br /&gt;
 #define DYN_DATA_ARRAY_SIZE_U32S                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''11: Timed Actions''&lt;br /&gt;
 #define NUMBER_OF_ACTION_ENTRIES                0  // ''User-modify field''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''12: Log entries base 2''&lt;br /&gt;
 #define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''13: OCEOS stack start Address''&lt;br /&gt;
 #define OCEOS_STACK_START_ADDRESS               0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''14: OCEOS stack end address''&lt;br /&gt;
 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * Not Used for ARM. Always Nested&lt;br /&gt;
     */&lt;br /&gt;
    app_config.interrupt_nesting_enabled     = TRUE;                          // Nesting Enabled&lt;br /&gt;
#endif&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * ARM SysTick is used for System Time&lt;br /&gt;
     */&lt;br /&gt;
    app_config.sys_time_timer_index          = SYS_TIME_TIMER_INDEX;          // 0 =&amp;gt; invalid index&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    // System time is used by timed actions, semaphores with timeout, dataqs with timeout, logging and profiling.&lt;br /&gt;
    // If all of above are not required then system time can be disabled. The system will not be interrupted by SysTick while CPU in sleep mode,&lt;br /&gt;
    //but it is not the case for SPARC targets,&lt;br /&gt;
    // as system time implemented by chaining two timers without interrupting.&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 '''Documentation'''/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 '''Examples'''/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 '''include'''/                             // OCEOS header files&lt;br /&gt;
 '''OCEOS_GCC_LIB'''/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 4 – Timer interrupt starts task&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1456</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1456"/>
		<updated>2022-03-31T15:15:41Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* OCEOS Normal operations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Normal operations&amp;lt;/span&amp;gt;====&lt;br /&gt;
The scheduling is started after calling [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The main structure of application flow is described below:&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] - Initialize fixed data and start system time and log&lt;br /&gt;
# Create:&lt;br /&gt;
## [[OCEOS/oceos kernel/task#oceos_task_create()|oceos_task_create()]] - Create task, setting priority, no of jobs, ..etc.&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/mutex#oceos_mutex_create()|oceos_mutex_create()]] - Create mutexes if require&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/dataq#oceos_dataq_create()|oceos_dataq_create()]] - Create data queues if require&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/semaphore#oceos_sem_create()|oceos_sem_create()]] - Create semaphores if require&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init_finish()|oceos_init_finish()]] - Initialize dynamic data area&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] - Start the scheduler and pass control to first task&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
It is mandatory to create the number of tasks, mutexes, semaphores, and data queues declared in oceos_config.h otherwise oceos_init_finish() will return an error.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OCEOS configuration parameters are shown below. In provided demo projects these are ''oceos_config.h'' and ''oceos_config.c''. More information can be found by clicking on the link for parameter that is of interest.&lt;br /&gt;
&lt;br /&gt;
 // ''1: Includes OCEOS main header file''&lt;br /&gt;
 #include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''2: Number of Log entries.''&lt;br /&gt;
 #define  [[OCEOS/oceos_logging#Logging_Configuration|NUMBER_OF_LOG_ENTRIES]]                   16 ''// 16 to 1024, default 64''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''3: Number of tasks''&lt;br /&gt;
 #define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);''&lt;br /&gt;
 //    ''Defaults to number of tasks, as each task should have aa least one job;''&lt;br /&gt;
 //    ''If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs''&lt;br /&gt;
 #define NUMBER_OF_READYQ_ENTRIES                10&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''5: Number of Mutexes''&lt;br /&gt;
 #define NUMBER_OF_MUTEXES                       2  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''6: Number of Semaphores''&lt;br /&gt;
 #define NUMBER_OF_SEMAPHORES                    0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''7: Number of Data Qs''&lt;br /&gt;
 #define NUMBER_OF_DATAQS                        0  // ''0 to 63''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''8: LOG data array size''&lt;br /&gt;
 #define LOG_DATA_ARRAY_SIZE_U32S                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''9: FIXED data array size''&lt;br /&gt;
 #define FIXED_DATA_ARRAY_SIZE_U32S              0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''10: DYNAMIC data array size''&lt;br /&gt;
 #define DYN_DATA_ARRAY_SIZE_U32S                0x100 // ''Calculated value. Read manual''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''11: Timed Actions''&lt;br /&gt;
 #define NUMBER_OF_ACTION_ENTRIES                0  // ''User-modify field''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''12: Log entries base 2''&lt;br /&gt;
 #define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''13: OCEOS stack start Address''&lt;br /&gt;
 #define OCEOS_STACK_START_ADDRESS               0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // ''14: OCEOS stack end address''&lt;br /&gt;
 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0  // ''Used by DMON OCEOS profile to display stack usage''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * Not Used for ARM. Always Nested&lt;br /&gt;
     */&lt;br /&gt;
    app_config.interrupt_nesting_enabled     = TRUE;                          // Nesting Enabled&lt;br /&gt;
#endif&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * ARM SysTick is used for System Time&lt;br /&gt;
     */&lt;br /&gt;
    app_config.sys_time_timer_index          = SYS_TIME_TIMER_INDEX;          // 0 =&amp;gt; invalid index&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    // System time is used by timed actions, semaphores with timeout, dataqs with timeout, logging and profiling.&lt;br /&gt;
    // If all of above are not required then system time can be disabled. The system will not be interrupted by SysTick while CPU in sleep mode,&lt;br /&gt;
    //but it is not the case for SPARC targets,&lt;br /&gt;
    // as system time implemented by chaining two timers without interrupting.&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 '''Documentation'''/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 '''Examples'''/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 '''include'''/                             // OCEOS header files&lt;br /&gt;
 '''OCEOS_GCC_LIB'''/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 4 – Timer interrupt starts task&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1455</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1455"/>
		<updated>2022-03-31T15:12:49Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* OCEOS Normal operations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Normal operations&amp;lt;/span&amp;gt;====&lt;br /&gt;
The scheduling is started after calling [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The main structure of application flow is described below:&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] - Initialize fixed data and start system time and log&lt;br /&gt;
# Create:&lt;br /&gt;
## [[OCEOS/oceos kernel/task#oceos_task_create()|oceos_task_create()]] - Create task, setting priority, no of jobs, ..etc.&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/mutex#oceos_mutex_create()|oceos_mutex_create()]] - Create mutexes if require&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/dataq#oceos_dataq_create()|oceos_dataq_create()]] - Create data queues if require&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/semaphore#oceos_sem_create()|oceos_sem_create()]] - Create semaphores if require&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init_finish()|oceos_init_finish()]] - Initialize dynamic data area&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] - Start the scheduler and pass control to first task&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
It is mandatory to create the number of tasks, mutexes, semaphores, and data queues declared in oceos_config.h otherwise oceos_init_finish() will return an error.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OCEOS configuration parameters are shown below. In provided demo projects these are ''oceos_config.h'' and ''oceos_config.c''. More information can be found by clicking on the link for parameter that is of interest.&lt;br /&gt;
&lt;br /&gt;
 // 1: Includes OCEOS main header file&lt;br /&gt;
 #include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // 2: Number of Log entries.&lt;br /&gt;
 #define  [[OCEOS/oceos_logging#Logging_Configuration|NUMBER_OF_LOG_ENTRIES]]                   16 // 16 to 1024, default 64&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // 3: Number of tasks&lt;br /&gt;
 #define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
 //    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
 //    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
 #define NUMBER_OF_READYQ_ENTRIES                10&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // 5: Number of Mutexes&lt;br /&gt;
 #define NUMBER_OF_MUTEXES                       2  // 0 to 63&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // 6: Number of Semaphores&lt;br /&gt;
 #define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // 7: Number of Data Qs&lt;br /&gt;
 #define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // 8: LOG data array size&lt;br /&gt;
 #define LOG_DATA_ARRAY_SIZE_U32S                0x100// Calculated value. Read manual&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // 9: FIXED data array size&lt;br /&gt;
 #define FIXED_DATA_ARRAY_SIZE_U32S              0x100// Calculated value. Read manual&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // 10: DYNAMIC data array size&lt;br /&gt;
 #define DYN_DATA_ARRAY_SIZE_U32S                0x100// Calculated value. Read manual&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // 11: Timed Actions&lt;br /&gt;
 #define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // 12: Log entries base 2&lt;br /&gt;
 #define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // 13: OCEOS stack start Address&lt;br /&gt;
 #define OCEOS_STACK_START_ADDRESS               0  // Used by DMON OCEOS profile to display stack usage&lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
 // 14: OCEOS stack end address&lt;br /&gt;
 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0  // Used by DMON OCEOS profile to display stack usage&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * Not Used for ARM. Always Nested&lt;br /&gt;
     */&lt;br /&gt;
    app_config.interrupt_nesting_enabled     = TRUE;                          // Nesting Enabled&lt;br /&gt;
#endif&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * ARM SysTick is used for System Time&lt;br /&gt;
     */&lt;br /&gt;
    app_config.sys_time_timer_index          = SYS_TIME_TIMER_INDEX;          // 0 =&amp;gt; invalid index&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    // System time is used by timed actions, semaphores with timeout, dataqs with timeout, logging and profiling.&lt;br /&gt;
    // If all of above are not required then system time can be disabled. The system will not be interrupted by SysTick while CPU in sleep mode,&lt;br /&gt;
    //but it is not the case for SPARC targets,&lt;br /&gt;
    // as system time implemented by chaining two timers without interrupting.&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 '''Documentation'''/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 '''Examples'''/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 '''include'''/                             // OCEOS header files&lt;br /&gt;
 '''OCEOS_GCC_LIB'''/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 4 – Timer interrupt starts task&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1454</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1454"/>
		<updated>2022-03-31T15:09:48Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* OCEOS Normal operations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Normal operations&amp;lt;/span&amp;gt;====&lt;br /&gt;
The scheduling is started after calling [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The main structure of application flow is described below:&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] - Initialize fixed data and start system time and log&lt;br /&gt;
# Create:&lt;br /&gt;
## [[OCEOS/oceos kernel/task#oceos_task_create()|oceos_task_create()]] - Create task, setting priority, no of jobs, ..etc.&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/mutex#oceos_mutex_create()|oceos_mutex_create()]] - Create mutexes if require&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/dataq#oceos_dataq_create()|oceos_dataq_create()]] - Create data queues if require&lt;br /&gt;
## [[OCEOS/oceos inter-task communication/semaphore#oceos_sem_create()|oceos_sem_create()]] - Create semaphores if require&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init_finish()|oceos_init_finish()]] - Initialize dynamic data area&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] - Start the scheduler and pass control to first task&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
It is mandatory to create the number of tasks, mutexes, semaphores, and data queues declared in oceos_config.h otherwise oceos_init_finish() will return an error.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OCEOS configuration parameters are shown below. In provided demo projects these are ''oceos_config.h'' and ''oceos_config.c''. More information can be found by clicking on the link for parameter that is of interest.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define  [[OCEOS/oceos_logging#Logging_Configuration|NUMBER_OF_LOG_ENTRIES]]                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                10&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x100// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x100// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x100// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0  // Used by DMON OCEOS profile to display stack usage&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0  // Used by DMON OCEOS profile to display stack usage&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * Not Used for ARM. Always Nested&lt;br /&gt;
     */&lt;br /&gt;
    app_config.interrupt_nesting_enabled     = TRUE;                          // Nesting Enabled&lt;br /&gt;
#endif&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * ARM SysTick is used for System Time&lt;br /&gt;
     */&lt;br /&gt;
    app_config.sys_time_timer_index          = SYS_TIME_TIMER_INDEX;          // 0 =&amp;gt; invalid index&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    // System time is used by timed actions, semaphores with timeout, dataqs with timeout, logging and profiling.&lt;br /&gt;
    // If all of above are not required then system time can be disabled. The system will not be interrupted by SysTick while CPU in sleep mode,&lt;br /&gt;
    //but it is not the case for SPARC targets,&lt;br /&gt;
    // as system time implemented by chaining two timers without interrupting.&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 '''Documentation'''/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 '''Examples'''/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 '''include'''/                             // OCEOS header files&lt;br /&gt;
 '''OCEOS_GCC_LIB'''/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 4 – Timer interrupt starts task&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1453</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1453"/>
		<updated>2022-03-31T10:01:37Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Normal operations&amp;lt;/span&amp;gt;====&lt;br /&gt;
The scheduling is started after calling [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]]. The main structure of application flow is described below:&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init()|oceos_init()]] – uses oceoc_init to Initialise fixed data and start system time and log&lt;br /&gt;
# [[OCEOS/oceos kernel/task#oceos_task_create()|oceos_task_create()]] - Create task setting priority, no of jobs, ..etc.&lt;br /&gt;
# [[OCEOS/oceos inter-task communication/mutex#oceos_mutex_create()|oceos_mutex_create()]]&lt;br /&gt;
# [[OCEOS/oceos inter-task communication/dataq#oceos_dataq_create()|oceos_dataq_create()]]&lt;br /&gt;
# [[OCEOS/oceos inter-task communication/semaphore#oceos_sem_create()|oceos_sem_create()]]&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_init_finish()|oceos_init_finish()]] – Initilise dynamic data area&lt;br /&gt;
# [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]] – Start the scheduler and pass control to first task&lt;br /&gt;
&lt;br /&gt;
After steps 1 to 4 above tasks implement application functionality. If mutexes, semaphores, dataqs and/or timed actions are required they also are created at step 2. &amp;lt;/br&amp;gt;&lt;br /&gt;
Note: it is mandatory to create the number of mutexes, semaphores, and dataqs declared otherwise oceos_init_finish() will return an error.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;TODO : describe oceos configuration with links to appropriate section in manual for more detailed information for each parameter&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                10&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x100// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x100// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x100// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * Not Used for ARM. Always Nested&lt;br /&gt;
     */&lt;br /&gt;
    app_config.interrupt_nesting_enabled     = TRUE;                          // Nesting Enabled&lt;br /&gt;
#endif&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
#ifdef __sparc__&lt;br /&gt;
    /**&lt;br /&gt;
     * FOR SPARC TARGET ONLY.&lt;br /&gt;
     * ARM SysTick is used for System Time&lt;br /&gt;
     */&lt;br /&gt;
    app_config.sys_time_timer_index          = SYS_TIME_TIMER_INDEX;          // 0 =&amp;gt; invalid index&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    // System time is used by timed actions, semaphores with timeout, dataqs with timeout, logging and profiling.&lt;br /&gt;
    // If all of above are not required then system time can be disabled. The system will not be interrupted by SysTick while CPU in sleep mode,&lt;br /&gt;
    //but it is not the case for SPARC targets,&lt;br /&gt;
    // as system time implemented by chaining two timers without interrupting.&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 '''Documentation'''/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 '''Examples'''/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 '''include'''/                             // OCEOS header files&lt;br /&gt;
 '''OCEOS_GCC_LIB'''/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 4 – Timer interrupt starts task&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_introduction&amp;diff=1452</id>
		<title>OCEOS/oceos introduction</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_introduction&amp;diff=1452"/>
		<updated>2022-03-31T09:53:44Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* OCEOS Configuration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt; =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
OCEOS is a pre-emptive real time operating system (RTOS) with a small memory footprint intended for hard real time systems that use the '''GR716 micro-controller, SPARC LEON2/3/4 processors and ARM Cortex-M micro-processors'''.&lt;br /&gt;
&lt;br /&gt;
It was developed by O.C.E. Technology with support from the European Space Agency (ESA) under project 4000127901/19/NL/AS and 4000135473/21/NL/GLC/js.&lt;br /&gt;
&lt;br /&gt;
This document describes the features and use of OCEOS, and details its behavior and system calls.&lt;br /&gt;
&lt;br /&gt;
*Real time software is often written as a set of trap/interrupt handlers and tasks managed by a RTOS.&lt;br /&gt;
*The trap/interrupt handlers start due to anomalous conditions or external happenings. They carry out the immediately necessary processing, and may ask the RTOS start a task to complete the processing.&lt;br /&gt;
*The RTOS starts tasks and schedules them for execution based on priority. In hard real time systems scheduling must ensure that each task completes no later than its deadline. Being early can also be a problem. &lt;br /&gt;
*OCEOS provides a timed output service (software timers) that allows an output be set for a precise system time independently of scheduling.&lt;br /&gt;
*OCEOS supports up to 255 tasks, and up to 15 current start requests for each task. &lt;br /&gt;
**Each task has a fixed priority. &lt;br /&gt;
**There are 254 task priorities, 1 (highest task priority) to 254 (lowest task priority). &lt;br /&gt;
**More than one task may have the same priority. &lt;br /&gt;
**Tasks of the same priority are FIFO scheduled.&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
Time slicing between tasks does not occur in OCEOS.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
*In OCEOS each task has a pre-emption threshold. A task can only be pre-empted by a task with a higher priority than this threshold. Pre-emptions and any traps/interrupts that occur will delay a task’s completion and potentially cause it to miss its deadline. Careful analysis is needed to ensure that task deadlines are always met.&lt;br /&gt;
*OCEOS supports this analysis and allows relatively simple determination of worst case behaviour.&lt;br /&gt;
*Problems such as unbounded priority inversion, chained blocking, and deadlocks cannot occur in OCEOS.&lt;br /&gt;
*OCEOS provides mutual exclusion semaphores (mutexes) to protect critical shared code or data, and inter-task communication using counting semaphores and data queues.&lt;br /&gt;
*A system state variable provides a summary of the current state of the system. &lt;br /&gt;
*Error conditions such as missed deadlines are logged and the system state variable updated. If the system state is not normal a user defined error handling function may be called and actions taken such as disabling a task or resetting the system.&lt;br /&gt;
*OCEOS does not allow dynamic creation of tasks at run time. &lt;br /&gt;
*Virtual memory is not supported.&lt;br /&gt;
*OCEOS is based on the Stack Resource Policy extension of the Priority Ceiling Protocol [https://www.math.unipd.it/~tullio/RTS/2009/Baker-1991.pdf Baker 1991].&lt;br /&gt;
*OCEOS is provided as a library and is statically linked with an application. &lt;br /&gt;
*Services not needed by an application are omitted by the linker.&lt;br /&gt;
&lt;br /&gt;
[[File:Oceos.png|800px]]&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Purpose of the Software&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
OCEOS is a real-time operating system suitable for use in single CPU hard real-time systems. Its design excludes potential problems such as unbounded priority inversion, chained blocking, and deadlocks. It is compact and uses only a single system stack rather than a stack for each task. It schedules up to 255 fixed priority tasks and allows use of mutual exclusion semaphores, counting semaphores and data queues. Its data areas are statically allocated and provide information on task execution that can be accessed at any time. Data outputs and task start requests can be specified to occur at a given system time in microseconds independent of scheduling. A system log and optional context switch log are part of error detection and handling.&lt;br /&gt;
&lt;br /&gt;
OCEOS is an object library for target architecture which provides directives to schedule fixed priority tasks, and supporting mutexes, semaphores, data queues, timed outputs, and interrupt handling.&amp;lt;br&amp;gt;&lt;br /&gt;
There are also directives for logging, error handling, GR716 memory protection and GR716 watchdog control. Only those components used by the application are linked into the executable.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Main Features&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
*Fixed priority preemptive scheduling&lt;br /&gt;
*Based on Stack Resource Policy – unbounded priority inversion, chained blocking, and deadlocks cannot occur&lt;br /&gt;
*Deterministic processing&lt;br /&gt;
*Fast real-time performance&lt;br /&gt;
*Single stack rather than separate stack for each task&lt;br /&gt;
*Small code footprint ( &amp;lt;10 kBytes for scheduling and mutex)&lt;br /&gt;
*Inter-task communication (Counting Semaphores and Data Queues)&lt;br /&gt;
*Synchronisation (Mutexes)&lt;br /&gt;
*Task preemption level&lt;br /&gt;
*Interrupt support (most of the directives can be called from IRQ handlers)&lt;br /&gt;
*Very short time for disabling interrupts&lt;br /&gt;
*Very low interrupt latency&lt;br /&gt;
*Nested interrupts support&lt;br /&gt;
*High precision timed actions (Software Timers) for data output and task start at pricise time&lt;br /&gt;
*Supports SPARC V8 LEON2/3/4 and ARM Cortex-M single core targets&lt;br /&gt;
*Fault Detection, Isolation and Recovety&lt;br /&gt;
*GR716 Memory protection functionality&lt;br /&gt;
*Enhancements for Cobham-Gaisler GR716 applications&lt;br /&gt;
*Sample Applications for Quick start&lt;br /&gt;
*Online Documentation&lt;br /&gt;
*Tutorial applications to demonstrate main features of OCEOS&lt;br /&gt;
*DMON debug tool support (execution timeline, CPU usage and profiling, commands to display information for OCEOS modules)&lt;br /&gt;
*Support &amp;amp; ISVV services available from OCE Technology Ltd.&lt;br /&gt;
*MISRA C Compliant&lt;br /&gt;
*Developed to ECSS Category B and ISO 26262 standards&lt;br /&gt;
*Developed in cooperation with European Space Agency (ESA)&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Memory Requirements&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
Memory usage depends on microcontroller, OCEOS modules and features, compilers and optimization level. &lt;br /&gt;
&lt;br /&gt;
Table below provides memory requirements for different targets. &lt;br /&gt;
Compiled with GNU GCC and optimization level 3. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Memory requirements for .text section of OCEOS, bytes&lt;br /&gt;
|-&lt;br /&gt;
! Section !! OCEOS Module !! (-O3) Size ARM Cortex-M7(thumb) !! (-O3) Size GR716 (REX) !! (-O3) Size LEON4&lt;br /&gt;
|-&lt;br /&gt;
| .text|| oceos_pendsv_handler.o      || 208           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| initialisation.o            || 2816          ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| oceos_start.o               || 1460          ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| interrupt.o                 || 44            ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| tasks.o                     || 3372          ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| task_create.o               || 400           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| task_disable.o              || 220           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| task_enable.o               || 144           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| task_info.o                 || 160           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| task_self.o                 || 76            ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| task_utils.o                || 192           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| task_kill.o                 || 108           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| logging.o                   || 400           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| logging_reset.o             || 176           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| logging_add.o               || 244           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| logging_remove.o            || 180           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| logging_size.o              || 72            ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| logging_utils.o             || 448           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| oceos_timer.o               || 340           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| cpu_sleep.o                 || 208           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| oceos_check_address_space.o || 4             ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
|      || '''Total Kernel'''          ||               ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| dataq.o                     || 284           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| dataq_clear.o               || 364           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| dataq_read_restart.o        || 260           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| dataq_read_restart_timeout.o|| 404           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| dataq_read_continue.o       || 140           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| dataq_write.o               || 684           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
|      || '''Total Dataq'''           ||               ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| mutex.o                     || 164           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| mutex_utils.o               || 608           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
|      || '''Total Mutex'''           ||               ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| semaphore.o                 || 268           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| semaphore_reset.o           || 304           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| semaphore_restart.o         || 264           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| semaphore_restart_timeout.o || 404           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| semaphore_continue.o        || 148           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| semaphore_signal.o          || 584           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
|      || '''Total Semaphore'''       ||               ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| timed_action.o              || 2136          ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| timed_action_init.o         || 208           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| timed_action_sem_remove.o   || 220           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| timed_action_dataq_remove.o || 240           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| timed_action_jobs.o         || 200           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| timed_action_output.o       || 184           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| timed_action_reset.o        || 320           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| timed_action_get_number.o   || 172           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| timed_action_jobs_remove.o  || 116           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| timed_action_output_remove.o|| 84            ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| timed_action_timer.o        || 96            ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| task_timed_start.o          || 828           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
|      || '''Total Timed Actions'''   ||               ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
| .text|| oceos_isr_cs_log.o          || 628           ||                       ||&lt;br /&gt;
|-                                                                                &lt;br /&gt;
|      || '''Total'''                 || 21811         ||                       ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;OCEOS Data Area Layouts&amp;lt;/span&amp;gt; ==&lt;br /&gt;
The design of OCEOS makes the contents of its data areas readily visible to an application. It is straightforward to determine the details of state of the system should it be necessary to do so.&amp;lt;br&amp;gt;&lt;br /&gt;
Each data area is made up of a number of fields whose sizes depend on the particular application but whose general layout is invariant.&amp;lt;br&amp;gt;&lt;br /&gt;
The layout of each area is described in ''oceos_areas.h'' which also provides the offset at which each field in an area is located if the above labels are defined before ''oceos_areas.h'' is included.&lt;br /&gt;
&lt;br /&gt;
Each field starts at a 32-bit boundary, so treating an area as an array of 32-bit words any field can be accessed by simply use the offset as an index into the array.&lt;br /&gt;
&lt;br /&gt;
Application developer must provide OCEOS with three data areas:&lt;br /&gt;
* Log data area&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S     0x100  // Number of words; Application dependent, must be modified by user &lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Fixed data area&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S   0x200  // Number of words; Application dependent, must be modified by user &lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Dynamic data area&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S     0x200  // Number of words; Application dependent, must be modified by user &lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
User can calculate required memory for each data area using following methods:&amp;lt;br&amp;gt;&lt;br /&gt;
* Use OCEOS provided Excel spread sheet. It can be downloaded [[Media:OCEOS_Config.xlsx | HERE]].&lt;br /&gt;
* Use ''oceos_areas.h'' header file &lt;br /&gt;
* Set values as big as possible, run application and use DMON command '''''oceos info''''' to display sizes of each data area in words. Update variables with these sizes.&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 DMON &amp;gt; oceos info&lt;br /&gt;
 Struct Field Name : *system_log_ptr                :: location 0x40016444 :: pointer 0x4001A0E0 :: size 0x109 :: sentinel OK&lt;br /&gt;
 Struct Field Name : *data_fixed_ptr                :: location 0x40016448 :: pointer 0x4001643C :: size 0x59  :: sentinel OK&lt;br /&gt;
 Struct Field Name : *data_dynamic_ptr              :: location 0x4001644C :: pointer 0x400180E0 :: size 0x258 :: sentinel OK&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Add function described below to application to display sizes of data areas. This function should be called after [[OCEOS/oceos kernel/initialisation#oceos_start()|oceos_start()]].&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;border-left-style: none;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
#define WORDS_USED_OFFSET       1U &lt;br /&gt;
&lt;br /&gt;
void display_data_area_sizes() {&lt;br /&gt;
	&lt;br /&gt;
  printf(&amp;quot;Log data area U32s = %p\n&amp;quot;,log_data[WORDS_USED_OFFSET]);&lt;br /&gt;
  printf(&amp;quot;Fixed data area U32s = %p\n&amp;quot;,fixed_data[WORDS_USED_OFFSET]);&lt;br /&gt;
  printf(&amp;quot;Dynamic data area U32s = %p\n&amp;quot;,dynamic_data[WORDS_USED_OFFSET]);&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
'''OCEOS data areas layout'''&lt;br /&gt;
 [[File:oceos data areas layout.jpg|none]] &lt;br /&gt;
'''OCEOS system data graph'''&lt;br /&gt;
 [[File:oceos memory layout diargam.jpg|none]]&lt;br /&gt;
&lt;br /&gt;
= &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Main Concepts'''&amp;lt;/span&amp;gt; =&lt;br /&gt;
&lt;br /&gt;
An application that uses OCEOS typically starts at main(), performs device initialization and other activities including setting up interrupt handlers, then starts OCEOS in two phases, an initialization phase and a scheduling phase. Tasks, mutexes etc. are only created in the initialization phase, resulting in a fixed data structure that is passed to the scheduling phase. OCEOS normally does not return to the application but will do so if it detects a fatal error.&lt;br /&gt;
&lt;br /&gt;
The specific application determines the tasks, mutexes and other OCEOS components used.&lt;br /&gt;
&lt;br /&gt;
The interrupt/trap handlers respond to events, do the immediately necessary processing, and typically ask OCEOS to start a task to complete the processing.&lt;br /&gt;
&lt;br /&gt;
OCEOS then creates an execution instance of the task, a ‘job’, and either puts it into immediate execution or on the ready queue or the timed jobs queue waiting to be scheduled for execution.&lt;br /&gt;
&lt;br /&gt;
OCEOS schedules jobs based on their priority and may pre-empt the processor from a job with a lower pre-emption threshold before that job completes in order to start a higher priority job.&lt;br /&gt;
&lt;br /&gt;
OCEOS maintains a system priority ceiling based on currently locked resources and the pre-emption threshold of the currently executing job. Only jobs with higher priority than this ceiling can pre-empt.&lt;br /&gt;
&lt;br /&gt;
Jobs with the same priority are scheduled according to time of arrival on the ready queue. Time slicing or pre-emption between jobs of the same priority does not take place.&lt;br /&gt;
&lt;br /&gt;
A job may have a deadline by which it must complete. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
It is the responsibility of the software developer to assign task priorities so that all jobs are guaranteed to meet their deadlines&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In OCEOS mutual exclusion of tasks is supported by mutexes. Counting semaphores and data queues support task synchronization and the exchange of data between jobs.&lt;br /&gt;
&lt;br /&gt;
Task start requests and data outputs (software timers) can be set to occur independently of scheduling at a given system time in microseconds.&lt;br /&gt;
&lt;br /&gt;
OCEOS maintains a system state variable and system log. If the state variable is not normal OCEOS may call a user defined function to deal with whatever condition has occurred.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tasks&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
In OCEOS all tasks are defined before scheduling begins and each task assigned a fixed priority, a pre-emption threshold, a current jobs limit, a maximum start to completion time, and an expected minimum inter start request time.&lt;br /&gt;
A task’s pre-emption threshold limits the tasks that can pre-empt it to those with higher priority than this threshold. Tasks with short run times can use this to avoid context switch overheads.&lt;br /&gt;
&lt;br /&gt;
Each task has two main states, enabled or disabled. OCEOS provides system calls to change task state. The state is usually enabled when the task is created, but can be initially disabled.&amp;lt;br&amp;gt;&lt;br /&gt;
A disabled task will not be executed, and any attempt to start it will be logged and the system state variable updated.&lt;br /&gt;
&lt;br /&gt;
A request to start an enabled task creates an execution instance of the task, a ‘job’. A count is kept for each task of the number of times it has been started, i.e. total number of jobs created.&amp;lt;br&amp;gt;&lt;br /&gt;
Multiple jobs of the same task can be in existence simultaneously. A limit for the maximum number of these current jobs is set when a task is created, the ‘current jobs limit’.&amp;lt;br&amp;gt;&lt;br /&gt;
Each task has a current jobs count. This increments each time a task is started and decrements on job completion unless completion creates a further job from this task.&amp;lt;br&amp;gt;&lt;br /&gt;
A further execution instance of a task is not created if the current jobs count has reached the current jobs limit. Such job creation failures are logged and the system state updated.&amp;lt;br&amp;gt;&lt;br /&gt;
For each task a record is kept of the shortest time between attempts to create a new job, and a record of the maximum time between these attempts.&amp;lt;br&amp;gt;&lt;br /&gt;
For each task a record is kept also of the maximum time a job was waiting before starting, the minimum execution time, the maximum execution time, the maximum time from job creation to completion, and the maximum number of job pre-emptions. The system state variable is updated if necessary.&lt;br /&gt;
&lt;br /&gt;
Task chaining is supported. A job can create a new job and pass this to the scheduler or place it on the timed actions queue.&lt;br /&gt;
&lt;br /&gt;
Tasks provide a start address for a termination routine for use if task execution must be abandoned.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Jobs&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
The request to start a task initializes a 'job', an execution instance of the task. A parameter is provided to allow an optional structure pointer be passed to the job.&amp;lt;br&amp;gt;&lt;br /&gt;
A job can require varying times to complete, with one exception its maximum execution time and maximum resource requirements are finite and known at compile time.&amp;lt;br&amp;gt;&lt;br /&gt;
This one exception is the unique lowest priority ‘idle job’, which if it exists has no execution time limitation. If there is no idle task OCEOS will place the CPU in sleep mode.&amp;lt;br&amp;gt;&lt;br /&gt;
Typically the ‘idle job’ is not idle, but used for system monitoring, logging, and initiating system correction activities. To save power it may put the CPU in sleep mode waiting for interrupts.&lt;br /&gt;
&lt;br /&gt;
A job has two principal states, pending and active. A pending job has not started execution and is either on the ready queue or on the pending jobs queue of a semaphore or data queue, or on the timed actions queue. Only pending jobs wait on resources. In OCEOS a pending job becomes active when it first starts execution. An active job is either running on the CPU or on the ready queue after being pre-empted.&amp;lt;br&amp;gt;&lt;br /&gt;
An active job may have to wait on the ready queue for the CPU but never has to wait for any other resource and is never on a pending jobs queue.&lt;br /&gt;
&lt;br /&gt;
For each job a record is kept of the time it was created, the time it became active, the execution time, the time it completed, and the number of times it was pre-empted.&lt;br /&gt;
&lt;br /&gt;
When a job completes, these job records are used to update the task records.&lt;br /&gt;
&lt;br /&gt;
Data can be passed between jobs of the same or different tasks by using statically allocated variables, counting semaphores, or data queues.&lt;br /&gt;
&lt;br /&gt;
A job may create another job and place this on the ready queue or on the timed actions queue.&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
If job can not continue because semaphore count is zero or data queue is empty, the job is put on pending queue for that semaphore or data queue and restarted when semaphore count is incremented or data is written to data queue. The user must take care to save information in data section, so the restarted job could continue without loss of already acquired data.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt; Ready Queue&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
This priority queue contains pending and active jobs ordered highest priority first, and within priority earliest arrival first.&amp;lt;br&amp;gt;&lt;br /&gt;
The scheduler places the first job on this queue into execution if and only if its priority is higher than the system priority ceiling. When it does so it updates the system priority ceiling to the pre-emption threshold of this job.&lt;br /&gt;
&lt;br /&gt;
OCEOS places pending jobs on this queue due to an interrupt or trap, or as a result of a system call from the current job, a semaphore signal or queue write, or a timeout.&amp;lt;br&amp;gt;&lt;br /&gt;
Each job in the Ready Queue is tagged with an ‘origin’ giving how the job came to be placed on the Ready Queue including time and identification of any other queue from which it was removed.&amp;lt;br&amp;gt;&lt;br /&gt;
There can be multiple occurrences of jobs from the same task on the Ready Queue, each with its origin. Initially this queue either contains the Idle Job, which must have the lowest priority, or is empty.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Timed Actions Queue&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
This is a priority queue of pending actions (software timers) and their associated times, with queue priority based on these times.&amp;lt;br&amp;gt;&lt;br /&gt;
It is linked to a high priority hardware timer which is set to interrupt at the time of the first action on the priority queue.&amp;lt;br&amp;gt;&lt;br /&gt;
When this interrupt occurs actions on the queue within a timing tolerance of the current time are carried out and the timer is reset to interrupt at the start time of the earliest remaining action.&amp;lt;br&amp;gt;&lt;br /&gt;
If the action is a task start request then at the set time the associated job is transferred to the ready queue, its origin set to timeout, and it is also removed from the pending list of any counting semaphore or data queue on which it is present. If the job is now the highest priority job on the ready queue it is started immediately, otherwise it must wait until that is the case.&amp;lt;br&amp;gt;&lt;br /&gt;
If the action is a data output then at the set time it is performed immediately.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;System Priority Ceiling&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
The value of this integer is the maximum priority of the priority ceilings of currently locked mutexes and the pre-emption threshold of the currently executing job. It is not directly accessible to an application.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Scheduling&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
OCEOS schedules jobs, i.e. execution instances of tasks created as a result of task start requests.&amp;lt;br&amp;gt;&lt;br /&gt;
The scheduler places a job into execution if and only if its priority is higher than the system priority ceiling. When it does so it updates the system priority ceiling to the pre-emption threshold of this job.&amp;lt;br&amp;gt;&lt;br /&gt;
Scheduling is pre-emptive and based on priority. The scheduler may pre-empt the processor from a lower priority job before that job completes to allow a higher priority job be started.&lt;br /&gt;
&lt;br /&gt;
Jobs with the same priority are scheduled based on the order of their arrival on the ready queue. Time slicing or pre-emption between jobs of the same priority does not occur.&amp;lt;br&amp;gt;&lt;br /&gt;
A job with a very short run time can avoid context switch overheads by having a high pre-emption threshold. This also allows pre-emption by some or all higher priority tasks be prevented. Such jobs with high pre-emption thresholds are scheduled based on their priority as usual.&amp;lt;br&amp;gt;&lt;br /&gt;
In OCEOS a wait for a mutex causes the system priority ceiling to be raised to the priority ceiling of the mutex unless it was already higher. The system priority ceiling returns to its previous value when the mutex is signaled.&lt;br /&gt;
&lt;br /&gt;
As a result the scheduler will not start any task that waits on that mutex until the mutex has been returned, as the mutex ceiling is the priority of the highest priority task that uses the mutex.&amp;lt;br&amp;gt;&lt;br /&gt;
(Instead of a higher priority job pre-empting a lower priority job but before termination returning control to a lower priority job and waiting for it to return a mutex, the wait for the mutex is done first.)&lt;br /&gt;
&lt;br /&gt;
In OCEOS context switching between tasks is minimized. A lower priority job only resumes execution when a higher priority job has completed, thus allowing stack sharing.&amp;lt;br&amp;gt;&lt;br /&gt;
In OCEOS problems such as priority inversion, chained blocking, and deadlocks cannot occur, all tasks can share the same stack thus saving memory, and schedulability analysis is simplified.&lt;br /&gt;
&lt;br /&gt;
Unnecessary blocking will occur for a job that does not use a mutex if it has a priority lower than the mutex priority ceiling and the mutex is currently held by a lower priority job.&amp;lt;br&amp;gt;&lt;br /&gt;
This un-necessary blocking may seldom occur, is limited in duration, and can be avoided by setting task priorities appropriately.&lt;br /&gt;
&lt;br /&gt;
This scheduling approach is based on the Stack Resource Policy extension of the Priority Ceiling Protocol [https://www.math.unipd.it/~tullio/RTS/2009/Baker-1991.pdf Baker 1991].&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Shared Resources&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
Many data structures cannot be fully accessed with a single instruction. Errors can result if a job using such a structure is pre-empted by another job that also uses the structure.&amp;lt;br&amp;gt;&lt;br /&gt;
To address this OCEOS provides up to 63 mutual exclusion semaphores ([[OCEOS/oceos inter-task communication/mutex|mutex]]). Each shared data structure or critical code segment typically is associated with its own mutex.&amp;lt;br&amp;gt;&lt;br /&gt;
Any job that uses a shared item should first acquire its mutex from OCEOS, and when finished with the item return the mutex. The number of instructions for which the mutex is held must be finite.&amp;lt;br&amp;gt;&lt;br /&gt;
OCEOS allows a mutex be held by only one job at any one time. A job that uses a shared data structure or critical code segment can use an associated mutex to exclude all other jobs.&amp;lt;br&amp;gt;&lt;br /&gt;
N.B. An OS does not prevent a shared resource being accessed if no attempt is made to acquire its mutex. The software developer must ensure this is done before the shared resource is used.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Inter-Job Communication&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
OCEOS provides two types of inter-job communication, counting semaphores and data queues. Semaphores and data queues are handled by OCEOS in a way different to many other OS.&amp;lt;br&amp;gt;&lt;br /&gt;
In most OS a job that waits on a zero semaphore or tries to read an empty data queue may be blocked at that point and wait there indefinitely or with an optional timeout.&amp;lt;br&amp;gt;&lt;br /&gt;
In OCEOS an active job may be pre-empted but cannot otherwise be blocked, so three options are provided in case a counting semaphore is zero when waited on or a data queue is empty when read.&lt;br /&gt;
&lt;br /&gt;
One option results in a value always being returned and the job continuing. The returned value will indicate that the semaphore was zero or queue empty, and the job can take this into account.&amp;lt;br&amp;gt;&lt;br /&gt;
In the other options, if the semaphore is zero or queue empty the job terminates and will restart from its beginning when the semaphore is signaled or queue written, or after an optional timeout.&lt;br /&gt;
&lt;br /&gt;
When the job becomes active again after a timeout and again encounters the second option the behavior is as with the first option, the job continues and takes into account that a timeout has occurred.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
Because a job restarts when a resource becomes available rather than waiting at the point where it sought the resource any local data developed up to that point will be lost unless stored non-locally for use after the restart. If required this can be done using static variables or structures, or using data queues or counting semaphores.&lt;br /&gt;
&amp;lt;/blockquote &amp;gt;&lt;br /&gt;
&lt;br /&gt;
In OCEOS event communication between tasks or between tasks and interrupt handlers is done typically by using counting semaphores.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Pending Jobs Queue&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
Each counting semaphore and data queue has an associated queue of pending jobs that are waiting for that semaphore or queue. Pending jobs also wait on the timed actions queue.&amp;lt;br&amp;gt;&lt;br /&gt;
Pending jobs queues contain only pending jobs and not active jobs, i.e. only jobs waiting to start execution.&amp;lt;br&amp;gt;&lt;br /&gt;
A pending job can be on a semaphore pending jobs queue or on a data queue pending jobs queue and also on the timed actions queue.&lt;br /&gt;
&lt;br /&gt;
The amount of time a job can spend on a semaphore or data queue pending jobs queue is of indefinite duration unless it is also on the timed actions queue.&lt;br /&gt;
&lt;br /&gt;
When a job is removed from a semaphore or data queue pending jobs queue its origin is set accordingly. It is also removed from the timed actions queue if present.&lt;br /&gt;
&lt;br /&gt;
When a timeout occurs and a job is removed from the timed actions queue its origin is set accordingly and it also is removed from a semaphore or data queue pending jobs queue if present.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
Mutexes do not having pending job queues. A pending job waiting for a mutex waits on the ready queue. Such waits are expected to be of short duration.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If it is necessary to pass data to a later job a job can do this before termination using static variables, static structures, data queues or counting semaphores.&lt;br /&gt;
&lt;br /&gt;
All jobs on a pending jobs queue are moved to the ready queue in the order of their arrival on the pending jobs queue before any of them is scheduled. Usually only one job is waiting on a pending jobs queue, if more than one a lower priority job may have to return to the pending jobs queue because a higher priority job or an earlier job has consumed the item. &lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;System State&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
OCEOS maintains a system state variable that is updated whenever there is anomalous behavior such as attempting to create more than the allowed number of jobs or writing to a queue that is full.&amp;lt;br&amp;gt;&lt;br /&gt;
If this variable is not its normal value, depending on the anomaly OCEOS may call a user defined function to deal with the anomaly.&amp;lt;br&amp;gt;&lt;br /&gt;
This typically reads the system log and the system state variable to determine the background to the detected anomaly.&lt;br /&gt;
&lt;br /&gt;
Please consult the header file codes.h for the system state variable codes. These include anomalies such as (the indexes below are not the codes used):&amp;lt;br&amp;gt;&lt;br /&gt;
* An attempt to start a disabled task&lt;br /&gt;
* An attempt to execute a task when its jobs limit is already reached.&lt;br /&gt;
* Job time from creation to completion exceeds allowed maximum for a task (deadline missed).&lt;br /&gt;
* Minimum time between job creations is less than the allowed minimum for task&lt;br /&gt;
* Ready queue unable to accept job as result of being full&lt;br /&gt;
* Mutex wait() when mutex already held&lt;br /&gt;
* Mutex signal() when not already held&lt;br /&gt;
* Mutex not returned before job terminates&lt;br /&gt;
* Attempt to add job to semaphore pending list when list full&lt;br /&gt;
* Data queue write when queue already full&lt;br /&gt;
* Attempt to add job to queue pending list when list full&lt;br /&gt;
* Timed job start write when timed actions queue already full&lt;br /&gt;
* Timed job start late job transfer to scheduler&lt;br /&gt;
* Timed output request when timed actions queue already full&lt;br /&gt;
* Timed output late&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;System Log&amp;lt;/span&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
This contains time stamped records of anomalies detected during execution. It is structured as a circular buffer. System calls are provided to initialize the log, set its maximum size, and return the number of entries.&lt;br /&gt;
&lt;br /&gt;
OCEOS will call a user defined function when the log is approximately 75% full.&lt;br /&gt;
&lt;br /&gt;
= &amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Definitions and Abbreviated Terms'''&amp;lt;/span&amp;gt; =&lt;br /&gt;
&lt;br /&gt;
The following gives terminology used in relation to OCEOS RTOS and some clarification notes.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''action''':&amp;lt;/span&amp;gt; something to be done at a specified system time.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS an action is done independently of task scheduling and is either a task start request or output of a value to an address.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''area''':&amp;lt;/span&amp;gt; a contiguous block of memory used for OCEOS internal data.&amp;lt;br&amp;gt;&lt;br /&gt;
 OCEOS does not use dynamic memory allocation to provide space for its internal data but instead sets up three statically defined areas based on the ASW configuration.&lt;br /&gt;
 The fixed data area holds information that does not change after all tasks etc. are created, the dynamic area holds information about tasks, jobs, etc. that changes as scheduling takes place, and the log area holds the system  state variable and the system log, which are always present, and if used the context switch log. The start addresses of the three areas are given by the ASW and must be 32-bit word aligned. Starting from these addresses each area is created by OCEOS as a block of 32-bit words that starts with OCEOS_VERSION followed by the count in words of the area size and ending with END_SENTINEL. The size of each area depends on the characteristics of the application, the number of tasks, mutexes, etc., and does not change once set up. OCEOS provides a header file oceos_areas.h which makes area sizes and field offsets available as defined constants if certain application characteristics are predefined as constants. OCEOS also uses a single system stack and a small amount of space on the heap.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''atomic''':&amp;lt;/span&amp;gt; an operation which once started does not allow other actors carry out the operation until the current operation has completed.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''application program interface (API)''':&amp;lt;/span&amp;gt; describes the application’s interface with OCEOS, usually referred to here as ‘directives’.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''context switch''':&amp;lt;/span&amp;gt; the change from executing the instruction codes of one task to executing those of another task.&amp;lt;br&amp;gt;&lt;br /&gt;
 Done by the OCEOS scheduler when it pre-empts a task.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''context switch latency''':&amp;lt;/span&amp;gt; the time taken to remember essential current task information and to set up or restore the new task’s information and put it into execution.&amp;lt;br&amp;gt;&lt;br /&gt;
 Please also refer to scheduling latency.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''context switch log''':&amp;lt;/span&amp;gt; a time-stamped record of context switches and switches to and from interrupt handlers for use by a debug monitor such as DMON.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''counter''':&amp;lt;/span&amp;gt; an unsigned integer typically updated by an interrupt or system call.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS a counter may involve 8 bits, 16 bits or 32 bits.&lt;br /&gt;
 In OCEOS a counter does not wrap around through zero but remains at its maximum/minimum value when this has been reached. &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''counting semaphore''':&amp;lt;/span&amp;gt; used to synchronize different tasks.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS a counting semaphore has a 32-bit counter, a pending jobs list, a semaphore create directive oceos_sem_create used only in system initialisation, a directive to return the counter value, a directive to return the number of pending list jobs, and four atomic directives, oceos_sem_signal, oceos_sem_wait_continue, oceos_sem_wait_restart, and oceos_sem_wait_restart_timeout.&lt;br /&gt;
 Signal operations and wait operations on a semaphore usually occur in different tasks.&lt;br /&gt;
 In OCEOS waiting on a semaphore has three options: continue, restart, restart with wait timeout. If the semaphore counter is non-zero all three options behave in the same way, decrementing the counter and returning a status code. If the semaphore counter is zero what happen depends on the option the ASW has chosen.&lt;br /&gt;
 N.B. In OCEOS a job does not block at the point where it does a wait operation on a zero semaphore, depending on the option chosen it either continues or terminates and restarts later. If a job uses the restart option, any local data at that point that is to be available after the job restarts needs to be stored globally as local data is lost when the job terminates.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''critical section''':&amp;lt;/span&amp;gt; a sequence of instructions that should not be in use by more than one task at a time.&amp;lt;br&amp;gt;&lt;br /&gt;
 Usually protected by a mutex that is locked at the start of the critical section and released at the end.&lt;br /&gt;
 N.B. Critical sections should be as short as possible.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''data queue''':&amp;lt;/span&amp;gt; in OCEOS a queue of non-null void pointers used to exchange data between tasks and to synchronize tasks.&amp;lt;br&amp;gt;&lt;br /&gt;
 It has a oceos_dataq_create directive that is only used during system initialisation, a data queue, a pending jobs list, a directive that returns the number of pointers on the data queue, a directive that returns the number of jobs on the pending list, and four atomic directives, oceos_dataq_write, oceos_dataq_read_continue,  oceos_dataq_read_restart, and oceos_dataq_read_restart_timeout.&lt;br /&gt;
 Write operations and read operations on a queue usually occur in different tasks.&lt;br /&gt;
 In OCEOS reading a queue has three options: continue, restart, restart with wait timeout. If the queue is non empty all three options behave in the same way, returning the pointer at the head of the queue. If the queue is empty what happen depends on the option the ASW has chosen.&lt;br /&gt;
 N.B. In OCEOS a job does not block at the point where it does a read operation on an empty queue, depending on the option chosen it either continues or terminates and restarts later. If a job uses the restart option, any local  data at that point that is to be available after the job restarts needs to be stored globally as local data is lost when the job terminates.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''deadlock''':&amp;lt;/span&amp;gt; a scheduling condition where jobs cannot proceed because each holds a resource the other needs.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS deadlocks cannot occur when mutexes are configured correctly.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''directive''':&amp;lt;/span&amp;gt; used by the application software to call an individual OCEOS function.&amp;lt;br&amp;gt;&lt;br /&gt;
 Directives provide control over tasks, message queues, semaphores, memory, timers etc.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''dynamic area''':&amp;lt;/span&amp;gt; area used by OCEOS for internal data that changes as part of normal scheduling operations, the area contents change but its size is constant.&amp;lt;br&amp;gt;&lt;br /&gt;
 It contains information such as e.g. the current system priority ceiling, the ready queue, states of tasks, jobs, mutexes etc.&lt;br /&gt;
 It is set up and initialised by oceos_start based on the fixed area information passed to it. Please also refer to ‘area’ above.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''error handling''':&amp;lt;/span&amp;gt; actions taken when OCEOS detects that a problem has occurred.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS error handling may involve one or a combination of (i)returning an appropriate status code (ii) making a system log entry (iii) updating the system state variable (iv) calling a user defined problem handling function (v) ending scheduling and exiting. If called the problem handling function can use the log, the system state variable, task and job timings and other data to determine the action that should be taken. If OCEOS detects corruption of its data areas it exits and returns to the ASW, which can access the system log, system state variable, and other information such as task timings.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''error hook''':&amp;lt;/span&amp;gt; a reference to the user defined function called when an abnormal condition is detected.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''event''':&amp;lt;/span&amp;gt; in some OS, but not in OCEOS, a job can suspend its own execution until a specified event occurs.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS an active job may be pre-empted by a higher priority job but never suspends itself.&lt;br /&gt;
 In OCEOS similar functionality is provided by a wait restart on a counting semaphore that is signalled later by an interrupt handler.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''fixed area''':&amp;lt;/span&amp;gt; area used by OCEOS for internal data that is defined in OCEOS initialisation and as tasks, mutexes etc. are created, this area does not change after oceos_init_finish is called.&amp;lt;br&amp;gt;&lt;br /&gt;
 It contains information such as number of tasks, task priorities, priority ceilings of mutexes, etc. The area is initialised by oceos_init and finalised after all tasks etc. have been created by oceos_init_finish, which adds an XOR checksum in the penultimate word. The fixed area is passed to oceos_start, which begins scheduling. Please also refer to ‘area’ above.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''hook''':&amp;lt;/span&amp;gt; a reference to a user defined function called by the operating system in certain conditions.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''idle job''':&amp;lt;/span&amp;gt; an execution instance of the unique lowest priority task, it is allowed to run indefinitely.&amp;lt;br&amp;gt;&lt;br /&gt;
 As OCEOS does not use time slicing and lower priority jobs wait for higher priority jobs to complete all other jobs should terminate after a finite time period.&lt;br /&gt;
 Typically this ‘idle job’ is not idle, but used for managing a watchdog timer, system monitoring and initiating system correction activities. To save power it may put the CPU in sleep mode waiting for interrupts (after disabling the watchdog if one is used).If no idle job is present OCEOS puts the CPU in sleep mode when no job is ready to run.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''initialization code''':&amp;lt;/span&amp;gt; this code executes when the CPU is reset and before main is called.&amp;lt;br&amp;gt;&lt;br /&gt;
 It is part of the BSP system used before main in the ASW.&lt;br /&gt;
 It is not part of OCEOS.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''interrupt''':&amp;lt;/span&amp;gt; a form of trap caused by an input to the CPU from an interrupt controller due to a change in state of one of the external links connected to the interrupt controller.&amp;lt;br&amp;gt;&lt;br /&gt;
 Please refer to ‘trap’.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''interrupt handler''':&amp;lt;/span&amp;gt; the code called when an interrupt occurs.&amp;lt;br&amp;gt;&lt;br /&gt;
 Please refer to ‘trap handler’.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''interrupt latency''':&amp;lt;/span&amp;gt; the time between the occurrence of the external interrupt condition and the execution of the first instruction of the interrupt handler.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''interrupt level''':&amp;lt;/span&amp;gt; the interrupt priority as determined by the CPU architecture and the interrupt controller.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''interrupt nesting''':&amp;lt;/span&amp;gt; occurs when an interrupt handler is interrupted by a higher priority interrupt.&amp;lt;br&amp;gt;&lt;br /&gt;
 Please see 'trap nesting'&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''interrupt service routine''':&amp;lt;/span&amp;gt; the interrupt handler associated with the interrupt.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''job''':&amp;lt;/span&amp;gt; a record of a request to start a task or the resulting execution instance of the task.&amp;lt;br&amp;gt;&lt;br /&gt;
 Please refer to ‘task job’.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''kernel mode''':&amp;lt;/span&amp;gt; the CPU mode in which all instructions are available for use and all physical memory addresses accessible.&amp;lt;br&amp;gt;&lt;br /&gt;
 N.B. When using OCEOS both the ASW and OCEOS are expected to run in kernel mode.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''log area''':&amp;lt;/span&amp;gt; an OCEOS memory area used to store system state information including the system state variable and the system log and if used the context switch log.&amp;lt;br&amp;gt;&lt;br /&gt;
 As this area is usually accessed only when a problem occurs, it may be stored in relatively slow external memory without impacting performance, and if this is non-volatile aspects of OCEOS state are preserved across power cycles.&lt;br /&gt;
 Please also refer to ’area’.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''manager''':&amp;lt;/span&amp;gt; a group of OCEOS directives with related functionality.&amp;lt;br&amp;gt;&lt;br /&gt;
 Managers may be core (used whenever OCEOS is used) or optional (selected or not by the application developer).&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''module''':&amp;lt;/span&amp;gt; OCEOS is structured as independent modules responsible for different OS features.&amp;lt;br&amp;gt;&lt;br /&gt;
 If a module is not used it is omitted at link time.&lt;br /&gt;
 Core manager modules are always present.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''mutex''':&amp;lt;/span&amp;gt; a binary semaphore used to provide mutual exclusion.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS each mutex has a priority ceiling. This is set when the mutex is created to the priority of the highest priority task that uses the mutex. If this is done correctly the design of OCEOS ensures that unbounded priority inversion, chained blocking, and deadlocks cannot occur, a significant advantage compared to most other RTOS.&lt;br /&gt;
 The wait and signal operations used to acquire and release a mutex should occur in pairs in the same task, and in a nested manner if multiple mutexes are used.&lt;br /&gt;
 The number of instruction executions between wait and signal must be finite and should be as short as possible.&lt;br /&gt;
 N.B. Mutexes provide mutual exclusion for tasks and not for interrupt handler code.&lt;br /&gt;
 N.B. The ASW is responsible for associating a mutex with a shared resource and ensuring it is used whenever the shared resource is accessed.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''mutual exclusion''':&amp;lt;/span&amp;gt; it must be possible for a task that is updating a resource to exclude other tasks from accessing the resource until updating is complete.&amp;lt;br&amp;gt;&lt;br /&gt;
 This is usually achieved by associating a specific mutex with each resource, and ensuring that any task that accesses the resource first acquires the mutex (wait) and releases it when access is complete (signal).&lt;br /&gt;
 Please refer to ‘mutex’.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''origin''':&amp;lt;/span&amp;gt; this indicates whence a pending job came when it was transferred to the ready queue.&amp;lt;br&amp;gt;&lt;br /&gt;
 The job may have just been created, or have been transferred from a pending jobs list as a result of a counting semaphore being signalled or data queue being written, or from a timed action queue as a result of a timeout.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''pending jobs list''':&amp;lt;/span&amp;gt; Each counting semaphore and each data queue has a pending jobs list of jobs waiting to be restarted when the resource becomes available.&amp;lt;br&amp;gt;&lt;br /&gt;
 Jobs are added to the list if the restart option is used and an attempt to wait on the semaphore or read the data queue fails.&lt;br /&gt;
 Following a signal or write all jobs on a pending list are transferred to the ready queue in the order in which they were placed on the list (FIFO), and the scheduler is called.&lt;br /&gt;
 Note: In OCEOS a mutex does not have a pending jobs list, jobs are only put into execution if all mutexes they require are free.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''pending jobs queue''':&amp;lt;/span&amp;gt; A queue of jobs organised based on priority rather than on arrival order, with usually no more than one job at a time removed from the queue.&amp;lt;br&amp;gt;&lt;br /&gt;
 The timed actions queue is a priority queue based on activation time.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''pre-empt''':&amp;lt;/span&amp;gt; the scheduler may pre-empt the processor from the currently running job when a job with higher priority than the current system priority ceiling is ready to start.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''pre-emption threshold''':&amp;lt;/span&amp;gt; a task’s pre-emption threshold restricts the tasks that can pre-empt it to those with higher priority than this threshold.&amp;lt;br&amp;gt;&lt;br /&gt;
 Please refer to ‘task pre-emption threshold’.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''priority''':&amp;lt;/span&amp;gt; a measure of urgency or importance.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS priorities range from 0 (highest priority) to 255 (lowesr priority).&lt;br /&gt;
 Priority levels 0 and 255 are reserved for internal OCEOS use.&lt;br /&gt;
 Task priorities are restricted to from 1 (highest) to 254 (lowest).&lt;br /&gt;
 Please refer to ‘task priority’.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''priority ceiling''':&amp;lt;/span&amp;gt; each mutex has a priority ceiling equal to the priority of the highest priority task that uses it.&amp;lt;br&amp;gt;&lt;br /&gt;
 This ceiling is determined by the ASW developer during code development and set when the mutex is created.&lt;br /&gt;
 OCEOS will only start a pending job if its priority is higher than the priority ceilings of all currently locked mutexes.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''priority ceiling protocol''':&amp;lt;/span&amp;gt; an approach to scheduling and to sharing resources.&amp;lt;br&amp;gt;&lt;br /&gt;
 OCEOS is based on an extension of this, the stack resource policy BAK91.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''priority inversion''':&amp;lt;/span&amp;gt; when a higher priority job has to wait in order to allow a lower priority job complete processing a shared resource and return a mutex.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS this wait occurs before the higher priority task starts. The maximum length of the wait can be determined during code development.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''priority inversion (unbounded)''':&amp;lt;/span&amp;gt; if a lower priority job can be pre-empted while holding a mutex the resulting delay to the return of the mutex by the low priority job can cause unbounded delays to a higher priority job that requires the mutex.&amp;lt;br&amp;gt;&lt;br /&gt;
 This cannot occur in OCEOS when mutexes are configured correctly.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''priority queue''':&amp;lt;/span&amp;gt; the order in which elements are removed is based on their priorities rather than on the order in which they arrived on the priority queue.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS the ready queue is a priority queue based on job priority and order of arrival, the timed actions queue is a priority queue based on time.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''queue''':&amp;lt;/span&amp;gt; A first in first out (FIFO) queue such as an OCEOS data queue.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''ready queue''':&amp;lt;/span&amp;gt; a priority queue of jobs with priority based on job priority and within priority on order of arrival.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS this holds references to pending jobs which have not yet started running, to active jobs that have been pre-empted, and to the currently executing job. A job is removed from the ready queue when it terminates.&lt;br /&gt;
 The OCEOS scheduler puts the first job on this queue into execution on the processor if and only if its priority is higher than the current system priority ceiling.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''resource''':&amp;lt;/span&amp;gt; may be a shared resource that can be accessed by different tasks.&amp;lt;br&amp;gt;&lt;br /&gt;
 Shared resources can give rise to many problems, please refer to 'mutual exclusion ' and ‘mutex’.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''running''':&amp;lt;/span&amp;gt; the running job is the job whose instructions are currently being executed on the processor.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS an active job is running unless interrupted or pre-empted, it is never in a suspended state waiting on a resource (other than the CPU).&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''scheduler''':&amp;lt;/span&amp;gt; a central part of an RTOS such as OCEOS, it determines which job should be executed on the processor.&amp;lt;br&amp;gt;&lt;br /&gt;
 In order to allow another job begin the scheduler may pre-empt the processor from the currently executing job.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''scheduling latency''':&amp;lt;/span&amp;gt; the time between the execution of the last instruction used in the old task and the execution of the first instruction used in the new task when the scheduler switches the processor between tasks.&amp;lt;br&amp;gt;&lt;br /&gt;
 It includes the context switch latency and the time taken by other scheduler actions.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''scheduling policy''':&amp;lt;/span&amp;gt; determines whether the currently executing job should be pre-empted.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS this is based on the stack resource policy with fixed task priorities and single resources BAK91. Pre-emption occurs if and only if the priority of the new job to be started is higher than the current system priority ceiling.&lt;br /&gt;
 N.B. By setting appropriate task priorities RMS and other systems can be used with OCEOS.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''semaphore''':&amp;lt;/span&amp;gt; Please refer to ‘counting semaphore’ and also to ‘mutex’.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''shutdown hook''':&amp;lt;/span&amp;gt; address of routine called to shut down the system.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''signal''':&amp;lt;/span&amp;gt; in OCEOS refers to a type of directive used to unlock a mutex or to attempt to increment a counting semaphore.&amp;lt;br&amp;gt;&lt;br /&gt;
 Please refer to ‘mutex’ and ‘counting semaphore’.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''sleep mode''':&amp;lt;/span&amp;gt; activities in the CPU are powered off except those required to monitor external interrupts.&amp;lt;br&amp;gt;&lt;br /&gt;
 When an interrupt is detected the CPU vectors to the corresponding interrupt handler and resumes normal execution.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''software component''':&amp;lt;/span&amp;gt; system settings data, initialisation code, trap handler, application tasks, and applicable OCEOS modules.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''stack resource policy''':&amp;lt;/span&amp;gt; an extension of the priority ceiling protocol that makes unbounded priority inversion, chained blocking and deadlocks impossible when mutexs are configured correctly and allows all tasks to share a single stack rather than requiring a separate stack for each task BAK91.&amp;lt;br&amp;gt;&lt;br /&gt;
 N.B. OCEOS is based on this policy.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''start a task''':&amp;lt;/span&amp;gt; create a job, put this job on the ready queue, and call the scheduler after allowing any interrupt nesting present to unwind.&amp;lt;br&amp;gt;&lt;br /&gt;
 Please see 'task start'&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''status code''':&amp;lt;/span&amp;gt; a code returned when an OCEOS directive is used indicating success or failure.&amp;lt;br&amp;gt;&lt;br /&gt;
 In most cases this is one of a predefined set of codes that indicate the type of problem if a problem has occurred, in one case a problem is indicated by return of a NULL pointer.&lt;br /&gt;
 N.B. The returned status code should always be checked when an OCEOS directive is used.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''suspended''':&amp;lt;/span&amp;gt; no jobs of the task are currently pending or active.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''system log''':&amp;lt;/span&amp;gt; used to record log entries made by OCEOS or by the ASW.&amp;lt;br&amp;gt;&lt;br /&gt;
 Stored in the OCEOS log data area whose start address is given by the application developer.&lt;br /&gt;
 Structured as an array of 64-bit log entries. The maximum number of log entries, which should be in the range 16 to 1024, is given by the application developer, with default 64.&lt;br /&gt;
 The log is treated as a circular buffer and the application developer can define a function to be called when the log becomes ¾ full.&lt;br /&gt;
 Log entries are preserved across system reset and if stored in non-volatile memory across power on-off cycles.&lt;br /&gt;
 Please refer to 'log area'.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''system priority ceiling''':&amp;lt;/span&amp;gt; an integer in the range 0 to 255, for a job to start it must be higher priority than the system priority ceiling.&amp;lt;br&amp;gt;&lt;br /&gt;
 Its value is set to 255 (lowest priority) at system start and subsequently determined by the pre-emption threshold of the currently executing job and the priority ceilings of any mutexes currently held.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''system priority ceiling stack''':&amp;lt;/span&amp;gt; used to hold successive system priority ceiling values on a LIFO basis, initialized to hold the value 255 (lowest priority).&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS this is a byte array with up to 256 entries (64 words), depending on the number of tasks in an application.&lt;br /&gt;
 Note: should not be confused with the system stack.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''system state variable''':&amp;lt;/span&amp;gt; this is updated by OCEOS when certain error conditions have been detected.&amp;lt;br&amp;gt;&lt;br /&gt;
 When OCEOS does so it may also call a user defined problem handling function that can access this variable, the system log, and timing and other information about tasks, etc. in deciding the action to take.&lt;br /&gt;
 This variable can be accessed by the ASW at any time and can be reset by the application. The variable is reset initially by oceos_init.&lt;br /&gt;
 A copy of this variable is also maintained by OCEOS, this copy is intended to provide a long term record of any problems that have occurred and can be reset and checked by the ASW.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''task''':&amp;lt;/span&amp;gt; the ASW involves a number of relatively independent tasks and also interrupt handling routines.&amp;lt;br&amp;gt;&lt;br /&gt;
 Each task has a principal function that is called to start job execution, and an optional termination function that can be used to terminate task execution in an orderly way if a task has to be aborted.&lt;br /&gt;
 Each task has a fixed priority and fixed pre-emption threshold and a fixed limit to the number of its jobs that can be pending or active simultaneously.&lt;br /&gt;
 The fixed task pre-emption threshold facilitates avoiding context switch overheads for task with very short execution times, and enables task pre-emption be restricted to tasks with significantly higher priorities if desired.&lt;br /&gt;
 OCEOS can be asked to start a task (create a job) before a previous execution of the task has completed, or even begun. A pointer is passed with a task start request that can be used to select the structure processed by a job. &lt;br /&gt;
 Please refer to ‘task job’.&lt;br /&gt;
 A task can be enabled or disabled, in the disabled state attempts to put it into execution fail but are logged.&lt;br /&gt;
 Data stored for each task includes number of times executed, maximum number of current execution instances, maximum number of times pre-empted, minimum time between start requests, maximum activation wait time, maximum execution time and maximum time from start request to completion. This data is updated each time one of the task’s jobs completes.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''task chaining''':&amp;lt;/span&amp;gt; a task can cause another task to start, optionally after a specified time.&amp;lt;br&amp;gt;&lt;br /&gt;
 When a task starts another task it may be pre-empted by the new task.&lt;br /&gt;
 A task can cause itself to restart, but should always choose an appropriate time delay before the restart occurs to ensure lower priority tasks are not locked out.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''task job''':&amp;lt;/span&amp;gt; a request to start a task or the resulting execution instance of the task.&amp;lt;br&amp;gt;&lt;br /&gt;
 A task start request can occur before a job created by a previous request has completed execution, or even begun execution, so a task can have a number of jobs waiting to begin execution.&lt;br /&gt;
 The maximum allowed number of jobs for a task is specified when the task is created.&lt;br /&gt;
 A request to start a task is accompanied by a pointer which is passed to the resulting job allowing different jobs of the same task act on different data.&lt;br /&gt;
 All jobs must complete in finite time with the exception of the idle job.&lt;br /&gt;
 Space to record each job’s information is set aside in the dynamic area by oceos_start.  A job is ‘free’ if its space is not in use, ‘pending’ if it has not yet started execution, ‘active’ if it has started execution.&lt;br /&gt;
 Only pending jobs are placed on pending jobs lists of semaphores or data queues or on the timed actions queue. Active jobs can be pre-empted by higher priority jobs but otherwise run to completion and are never on pending jobs  lists or on the timed actions queue.&lt;br /&gt;
 Data stored for each job includes origin, creation time, activation time, execution time, time to completion, and number of pre-emptions. This job data is used to update the task data when a job terminates.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''task jobs limit''':&amp;lt;/span&amp;gt; this integer is the maximum number of a task’s jobs that can be current, i.e. pending or active at the same time.&amp;lt;br&amp;gt;&lt;br /&gt;
 It is set when the task is created in the range 1 to 15. It should be set to 2 or more unless it is certain that a task start request cannot occur while a task job is already active or pending.&lt;br /&gt;
 N.B. An attempt to create more than this number of current jobs will fail with an error status  being returned, a log entry being made, and the system state variable being updated.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''task pre-emption threshold''':&amp;lt;/span&amp;gt; a task’s pre-emption threshold restricts the tasks that can pre-empt it to those with higher priority than this threshold.&amp;lt;br&amp;gt;&lt;br /&gt;
 A task’s pre-emption threshold is fixed and set when the task is created. It is never lower priority than the task’s priority.&lt;br /&gt;
 A high threshold can be used to prevent pre-emption and avoid context switch overheads for tasks with short run times.&lt;br /&gt;
 A threshold can also be used to allow only the highest priority tasks pre-empt a task while dis-allowing pre-emption by some higher priority tasks.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''task priority''':&amp;lt;/span&amp;gt; a measure of the urgency associated with executing a task’s instructions.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS task priorities are integers in the range 1 (highest task priority) to 254 (lowest task priority) and are fixed when a task is created. More than one task can have the same priority.&lt;br /&gt;
 If a task does not terminate (e.g. the idle task) it must have the lowest task priority to avoid locking out lower priority tasks, and should be the only task with that priority.&lt;br /&gt;
 Tasks with the same priority are executed in FIFO order. Time-slicing or pre-emption between tasks of the same priority does not occur in OCEOS.&lt;br /&gt;
 Please refer also to ‘priority’.&lt;br /&gt;
 N.B. Selecting appropriate priorities for tasks is a key responsibility of the application developer.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''task start''':&amp;lt;/span&amp;gt; create a job, put this job on the ready queue, and call the scheduler after allowing any interrupt nesting present to unwind.&amp;lt;br&amp;gt;&lt;br /&gt;
 If the task has higher priority than the current system priority ceiling the scheduler will pre-empt the current active job and place the new job into execution.&lt;br /&gt;
 In OCEOS after a job is created it remains in a ‘pending’ state until it is first put into execution on the processor, becoming ‘active’ once it has started execution.&lt;br /&gt;
 N.B. If the number of current jobs for this task is already at this task’s jobs limit, a new job will not be created and an error will be reported.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''task state''':&amp;lt;/span&amp;gt; in OCEOS a task has two states, enabled and disabled.&amp;lt;br&amp;gt;&lt;br /&gt;
 OCEOS provides directives to switch a task between states. A task start request only creates a job if the task is enabled.&lt;br /&gt;
 Disabling a task terminates all pending jobs of that task. A task can only be re-enabled once a previous disabling has completed.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''terminate''':&amp;lt;/span&amp;gt; when a job finishes execution it is said to terminate.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS every job except perhaps the idle job terminates after a finite execution time. A job usually terminates itself by exiting its principal function or by calling its termination function.&lt;br /&gt;
 In OCEOS an active job automatically terminates and becomes a pending job on the pending jobs list of a counting semaphore or data queue and/or on the timed actions queue if nothing is available when accessing the semaphore or  data queue and the restart option has been chosen. The job restarts when the semaphore is signalled or queue written, or after a timeout.&lt;br /&gt;
 OCEOS terminates all a task’s pending jobs when it disables a task.&lt;br /&gt;
 On job termination OCEOS updates task parameters such as maximum time to completion and maximum number of pre-emptions.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''timed actions queue''':&amp;lt;/span&amp;gt; a priority queue of pending actions and their associated starts times, with queue priority based on time.&amp;lt;br&amp;gt;&lt;br /&gt;
 It is linked to a timer which is set to interrupt at the time of the first action on the priority queue.&lt;br /&gt;
 After the timed actions have been carried out the timer is reset to interrupt at the start time of the earliest remaining action.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''timed action''':&amp;lt;/span&amp;gt; an action to be done at a specified time involving either transferring a pending job to the ready queue or outputting a value to an address.&amp;lt;br&amp;gt;&lt;br /&gt;
 Involves specifying a forward time tolerance and a backward time tolerance. When a timed action occurs this action and other actions whose forward timing tolerances include the current time are carried out. The backward tolerance allows the action be performed if the current time is later than the requested time by no more than this amount. If set to zero late actions are not performed.&lt;br /&gt;
 All late actions are logged and the system state variable updated.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''trap''':&amp;lt;/span&amp;gt; causes a transfer of control to an address associated with the trap’s identity number.&amp;lt;br&amp;gt;&lt;br /&gt;
 There are three main types of trap. Exceptions are generated by the CPU itself as a result of some exceptional condition such as divide by zero. Software traps are generated by special software trap instructions that give the trap number. Interrupts are caused by external devices usually via an interrupt controller.&lt;br /&gt;
 N.B. Traps should be disabled for the minimum time possible to avoid missing interrupts or delaying the response to them.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''trap handler''':&amp;lt;/span&amp;gt; code that takes the steps immediately necessary to deal with a trap (including interrupts).&amp;lt;br&amp;gt;&lt;br /&gt;
 This code may request OCEOS to start a task, if for an interrupt this code typically resets the cause of the interrupt.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''trap vector table''':&amp;lt;/span&amp;gt; traps (including interrupts) use their identity number to vector to a location in this table which determines the handler code to use.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''user mode''':&amp;lt;/span&amp;gt; code running in user mode must delegate most access to hardware to kernel mode software, typically using a software trap or traps.&amp;lt;br&amp;gt;&lt;br /&gt;
 This mode is often not used in embedded software where the application code typically requires direct access to the hardware.&lt;br /&gt;
 N.B. In OCEOS application code is expected to run in kernel mode not in user mode.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''wait''':&amp;lt;/span&amp;gt; in OCEOS refers to a type of directive used to attempt to lock a mutex or to decrement a counting semaphore.&amp;lt;br&amp;gt;&lt;br /&gt;
 OCEOS does not provide a wait(event) directive, a similar capability can be provided by an interrupt caused by an event signaling a counting semaphore.&lt;br /&gt;
 Please refer to ‘mutex’ and ‘counting semaphore’.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''waiting''':&amp;lt;/span&amp;gt; a state in which a task/job has commenced execution but is not able to continue and must wait for a resource, usually retaining its current stack frame and other context and &lt;br /&gt;
 allowing lower priority tasks/jobs run. In OCEOS this state cannot occur.&amp;lt;br&amp;gt;&lt;br /&gt;
 In OCEOS waiting is done only by a pending job, i.e. a job that has not yet started execution and so has no current stack frame, such jobs are described as ‘pending’ rather than ‘waiting’. An active job, i.e. a job that has &lt;br /&gt;
 commenced execution, may be pre-empted by a higher priority job and have to wait to regain the CPU until a higher priority task finishes, but never is delayed by anything except termination of a higher priority job or the ending of an interrupt handling routine.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''warning''':&amp;lt;/span&amp;gt; an OCEOS action that indicates execution was not normal.&amp;lt;br&amp;gt;&lt;br /&gt;
 OCEOS provides different warnings, including returned status codes, system log entries, system state updates, calls to a user defined function, and in the worst case exit from OCEOS.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#0c6bb3&amp;quot;&amp;gt;'''watchdog timer''':&amp;lt;/span&amp;gt; a timer connected to the processor reset input so that a system reset will be caused if the timer times out.&amp;lt;br&amp;gt;&lt;br /&gt;
 Usually the lowest priority task has responsibility for resetting the timer before this happens. The timeout interval is chosen so that all higher priority tasks will have completed within the interval thus allowing return to the lowest priority task that then resets the timer. Protects against system lockups due to infinite loops and transient hardware problems.&lt;br /&gt;
 N.B. Creation and management of a watchdog timer is the responsibility of the ASW.&lt;br /&gt;
&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1451</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1451"/>
		<updated>2022-03-30T17:31:24Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* Content of Customer Release */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 '''Documentation'''/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 '''Examples'''/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 '''include'''/                             // OCEOS header files&lt;br /&gt;
 '''OCEOS_GCC_LIB'''/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 4 – Timer interrupt starts task&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1450</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1450"/>
		<updated>2022-03-30T17:30:38Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* Tutorial 4 – Timer interrupt starts task */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 Documentation/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 Examples/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 include/                             // OCEOS header files&lt;br /&gt;
 OCEOS_GCC_LIB/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 4 – Timer interrupt starts task&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1449</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1449"/>
		<updated>2022-03-30T17:29:42Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* Tutorial 5 – Using dataq with timed action */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 Documentation/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 Examples/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 include/                             // OCEOS header files&lt;br /&gt;
 OCEOS_GCC_LIB/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorial 4 – Timer interrupt starts task ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 5 – Using dataq with timed action&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1448</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1448"/>
		<updated>2022-03-30T17:28:10Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* Tutorial 3 – Using Semaphores */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 Documentation/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 Examples/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 include/                             // OCEOS header files&lt;br /&gt;
 OCEOS_GCC_LIB/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 3 – Using Semaphores&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorial 4 – Timer interrupt starts task ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorial 5 – Using dataq with timed action ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1447</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1447"/>
		<updated>2022-03-30T17:27:14Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* Tutorial 2 – Using a mutex */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 Documentation/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 Examples/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 include/                             // OCEOS header files&lt;br /&gt;
 OCEOS_GCC_LIB/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorial 3 – Using Semaphores ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorial 4 – Timer interrupt starts task ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorial 5 – Using dataq with timed action ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1446</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1446"/>
		<updated>2022-03-30T17:27:06Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* Tutorial 2 – Using a mutex */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 Documentation/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 Examples/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 include/                             // OCEOS header files&lt;br /&gt;
 OCEOS_GCC_LIB/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 2 – Using a mutex&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#  Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorial 3 – Using Semaphores ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorial 4 – Timer interrupt starts task ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorial 5 – Using dataq with timed action ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1445</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1445"/>
		<updated>2022-03-30T17:26:29Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* OCEOS Demo Tutorials */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 Documentation/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 Examples/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 include/                             // OCEOS header files&lt;br /&gt;
 OCEOS_GCC_LIB/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Tutorial 1 – Starting tasks&amp;lt;/span&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorial 2 – Using a mutex ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#  Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorial 3 – Using Semaphores ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorial 4 – Timer interrupt starts task ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorial 5 – Using dataq with timed action ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1444</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1444"/>
		<updated>2022-03-30T17:25:08Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* Tutorial 5 – Using dataq with timed action */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 Documentation/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 Examples/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 include/                             // OCEOS header files&lt;br /&gt;
 OCEOS_GCC_LIB/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
=== Tutorial 1 – Starting tasks ===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorial 2 – Using a mutex ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#  Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorial 3 – Using Semaphores ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorial 4 – Timer interrupt starts task ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorial 5 – Using dataq with timed action ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of data queue with timeouts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1443</id>
		<title>OCEOS/oceos use</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_use&amp;diff=1443"/>
		<updated>2022-03-30T17:22:00Z</updated>

		<summary type="html">&lt;p&gt;Okhoruzhyy: /* OCEOS Demo Tutorials */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Introduction'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
OCEOS is provided as an object library, documentation and example source code.&amp;lt;br&amp;gt;&lt;br /&gt;
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The OCEOS build and test environment requires the following:&amp;lt;/p&amp;gt;&lt;br /&gt;
# SPARC Build environment (compiler, linker, libraries, etc.) [https://www.gaisler.com/index.php/downloads/compilers?task=view&amp;amp;id=161 Download here].&lt;br /&gt;
# ARM Build environment [https://developer.arm.com/tools-and-software/embedded/arm-compiler Download here] and [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm Download here]&lt;br /&gt;
# Debug software tool e.g. OCE’s DMON. [http://ocetechnology.com/?page_id=306 Evaluation download].&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Content of Customer Release&amp;lt;/span&amp;gt;====&lt;br /&gt;
 Documentation/&lt;br /&gt;
              OCEOS_User_Manual.pdf   // OCEOS User Manual&lt;br /&gt;
 Examples/&lt;br /&gt;
          AreaDisplay/                // OCEOS project to display sizes of data areas described [[OCEOS/oceos_introduction#OCEOS_Data_Area_Layouts|HERE]]&lt;br /&gt;
          arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below&lt;br /&gt;
          asw/                        // DEMO project of main OCEOS features&lt;br /&gt;
          SampleProject/              // Skeleton project that can be used to start development  &lt;br /&gt;
          tut1/                       // This project demonstrates starting tasks with different priorities.&lt;br /&gt;
          tut2/                       // This project familiarize the developer with the use a mutexes.&lt;br /&gt;
          tut3/                       // This project demonstrates the use of semaphores for task synchronization.&lt;br /&gt;
          tut4/                       // This project introduces the use of timer interrupts to start the task.&lt;br /&gt;
          tut5/                       // This project introduces the use of data queue with timeouts.&lt;br /&gt;
 include/                             // OCEOS header files&lt;br /&gt;
 OCEOS_GCC_LIB/&lt;br /&gt;
               liboceos.lib           // OCEOS library that can be linked with application&lt;br /&gt;
               README.txt             // Notes&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;Building the example application&amp;lt;/span&amp;gt;====&lt;br /&gt;
OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in ''tools_config_arm.mk'' to point to toolchain folder.&lt;br /&gt;
User can use make files to build project for one of the supported development board. &lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;background-color: #c6e2f7; border-left-style: solid; border-left-width: 3px; border-left-color: blue; &amp;quot;&amp;gt; '''Note'''&amp;lt;br&amp;gt;&lt;br /&gt;
User requires to modify make files to add own development board.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for ARM:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* ARM_BUILD=1&lt;br /&gt;
* TOOLCHAIN=armclangv6|gcc|segger|iar&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MCPU=cortex-m3|cortex-m7&lt;br /&gt;
* BOARD=ATSAM3X8E|ATSAMV71Q21&lt;br /&gt;
* FPU=0|1&lt;br /&gt;
* SAMV71_CONSOLE=0|1&lt;br /&gt;
 Example:&lt;br /&gt;
 make all FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21&lt;br /&gt;
&lt;br /&gt;
Make file available parameters for SPARC:&amp;lt;br&amp;gt;&lt;br /&gt;
* Build target: all&lt;br /&gt;
* TOOLCHAIN=gcc|clang&lt;br /&gt;
* RELEASE=0|1&lt;br /&gt;
* MREX=1&lt;br /&gt;
* BSP=gr716|pm698|gr712rc|gr740|agga4|at697&lt;br /&gt;
 Example:&lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716&lt;br /&gt;
 or &lt;br /&gt;
 make all TOOLCHAIN=clang BSP=gr716 MREX=1&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''OCEOS Demo Tutorials'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
=== Tutorial 1 – Starting tasks ===&lt;br /&gt;
&lt;br /&gt;
This exercise demonstrates starting tasks with different priorities.&lt;br /&gt;
&lt;br /&gt;
# Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.&lt;br /&gt;
# Each task outputs a message when it starts, another message when it exits.&lt;br /&gt;
# Start OCEOS with the low priority task.&lt;br /&gt;
# This starts the high priority task and then exits.&lt;br /&gt;
# The high priority task starts the low priority tasks and exits.&lt;br /&gt;
For code example see below.&lt;br /&gt;
&lt;br /&gt;
'''''tut.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT1_H_&lt;br /&gt;
#define TUT1_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT1_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut1.c'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut1.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered high priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_1, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving high priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Entered low priority task\n&amp;quot;);&lt;br /&gt;
  oceos_task_start(t_0, ptr);&lt;br /&gt;
  printf(&amp;quot;Leaving low priority task\n&amp;quot;);&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorial 2 – Using a mutex ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise will familiarise the developer with the use a mutexes.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#  Two tasks as before.&lt;br /&gt;
# One mutex. Note the priority ceiling of the mutex.&lt;br /&gt;
# Both tasks output message when they get the mutex and when they return it&lt;br /&gt;
# Start OCEOS with the low priority task&lt;br /&gt;
# This grabs mutex, then starts high priority task&lt;br /&gt;
# Low priority task returns mutex then exits&lt;br /&gt;
# High priority task returns mutex, start low priority task and exits&lt;br /&gt;
&lt;br /&gt;
For code example see example below:&lt;br /&gt;
&lt;br /&gt;
'''''tut2.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT2_H_&lt;br /&gt;
#define TUT2_H_&lt;br /&gt;
&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // High priority task&lt;br /&gt;
    t_1                  // Low priority task&lt;br /&gt;
};&lt;br /&gt;
/* Sample Mutex names - all here start with m_ to help avoid name confusion */&lt;br /&gt;
enum MUTEX_NAME{&lt;br /&gt;
    m_0&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT2_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       1  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut2.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut2.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;mutex.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        100,// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        100,	// threshold, must be in range 1 to task priority&lt;br /&gt;
                        2,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 4;&lt;br /&gt;
  }   // if&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;high priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start lower priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from high priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;High priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task getting mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task got mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  oceos_task_start(t_0, ptr);	// Start higher priority task&lt;br /&gt;
&lt;br /&gt;
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {&lt;br /&gt;
    printf(&amp;quot;Error from low priority task releasing mutex\n&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    printf(&amp;quot;Low priority task released mutex\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorial 3 – Using Semaphores ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Semaphores can be used to synchronise task actions as in this exercise.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Three tasks this time, one high priority and the other two with the same lower priority&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First task starts second and third tasks&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Second task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘item done’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Third task loops&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: lower-latin;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;wait_restart items&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Output ‘got item’ message&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;signal spaces&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut3.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT3_H_&lt;br /&gt;
#define TUT3_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to start other two&lt;br /&gt;
    t_1,                 // consumer task&lt;br /&gt;
    t_2                  // consumer task&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */&lt;br /&gt;
enum SEM_NAME{&lt;br /&gt;
    items,                   // Semaphore called items&lt;br /&gt;
    spaces                   // Semaphore called spaces&lt;br /&gt;
};&lt;br /&gt;
char* nullPtr = &amp;quot;&amp;quot;;			// Need pointer to pass to oceos_start&lt;br /&gt;
void (*nullFun)(void *);	// Null function&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void fun2(void *);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT3_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         3  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut3.c'''''&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut3.h&amp;quot;                        // application header&lt;br /&gt;
#include &amp;quot;semaphore.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        nullFun,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 3;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2&lt;br /&gt;
    return 4;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 6;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Application code functions, functions declared in asw.h&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  oceos_task_start(t_1, ptr);	// Start consumer task&lt;br /&gt;
  oceos_task_start(t_2, ptr);	// Start consumer task&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 task waiting items\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;Got item\n&amp;quot;);&lt;br /&gt;
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_0 signalling spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}   // fun0()&lt;br /&gt;
&lt;br /&gt;
void fun2(void *ptr) {&lt;br /&gt;
  while (1) {	// loop forever&lt;br /&gt;
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 task waiting spaces\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (oceos_sem_signal(items) != SUCCESSFUL) {&lt;br /&gt;
      printf(&amp;quot;Error from task t_1 signalling items\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      printf(&amp;quot;Item done\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorial 4 – Timer interrupt starts task ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of timer interrupts.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create one task&lt;br /&gt;
# Set a timer to interrupt every 2 seconds&lt;br /&gt;
# Set timer handler to start task&lt;br /&gt;
# Task outputs message, then exits &lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut4.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef TUT4_H_&lt;br /&gt;
#define TUT4_H_&lt;br /&gt;
/* Sample Task names - all here start with t_ to help avoid name confusion */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_0,                 // Task to setup interrupt&lt;br /&gt;
    t_1                  // Task to be executed by interrupt routine&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *);&lt;br /&gt;
void fun1(void *);&lt;br /&gt;
void start_task(void *arg, int source);&lt;br /&gt;
void timer_setup(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* TUT4_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * ARM specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
//--------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Must be defined if Application is using :&lt;br /&gt;
 *      Dataq with timeout&lt;br /&gt;
 *      Semaphore with timeout&lt;br /&gt;
 *      Timed Actions&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error() {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''arm_task_src.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up timer and register handler&lt;br /&gt;
 */&lt;br /&gt;
void timer_setup(){&lt;br /&gt;
&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID28;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
   // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
 //tc-&amp;gt;TC_RC  = base_scaler * 0x3DC6C0;&lt;br /&gt;
 tc-&amp;gt;TC_RC  = base_scaler * 1349;&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
  // Enabling Peripheral Clocks&lt;br /&gt;
 // REmove write protect&lt;br /&gt;
 int pmc_was_enabled = 0;&lt;br /&gt;
 if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
     PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     pmc_was_enabled = 1;&lt;br /&gt;
 }&lt;br /&gt;
 // Enable Clock&lt;br /&gt;
 PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID24;&lt;br /&gt;
 // Enable write protect&lt;br /&gt;
 if (pmc_was_enabled) {&lt;br /&gt;
   PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
 }&lt;br /&gt;
 timer_regs = (Tc *)TC0;&lt;br /&gt;
 tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[1]);&lt;br /&gt;
&lt;br /&gt;
 // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //&lt;br /&gt;
&lt;br /&gt;
 // Set Block Clock&lt;br /&gt;
 timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; 1));&lt;br /&gt;
 // Interrupt Enable&lt;br /&gt;
 // Enable Timer interrupt (RC Compare)&lt;br /&gt;
 tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
 NVIC_EnableIRQ(TC1_IRQn);&lt;br /&gt;
 // Set Highest Priority for interrupt number&lt;br /&gt;
 NVIC_SetPriority(TC1_IRQn, 1);&lt;br /&gt;
&lt;br /&gt;
 tc-&amp;gt;TC_RC  = 0x61a8;// 1s&lt;br /&gt;
&lt;br /&gt;
 // Enable clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
 // Start clock&lt;br /&gt;
 tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}   // setup_timer()&lt;br /&gt;
&lt;br /&gt;
void TC1_IRQHandler() {&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_SR;// Read to remove pending bit&lt;br /&gt;
#endif&lt;br /&gt;
  // Start task&lt;br /&gt;
  oceos_task_start(t_1, NULL);&lt;br /&gt;
&lt;br /&gt;
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''tut4.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 *********************************************************************************************************&lt;br /&gt;
 *                                                OCEOS&lt;br /&gt;
 *                                      Real-Time Operating System&lt;br /&gt;
 *                                                 for&lt;br /&gt;
 *                                        ARM Microcontroller&lt;br /&gt;
 *&lt;br /&gt;
 *                                   Example implementation of OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 *                               (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
 *                                           All Rights Reserved&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * Author:       jfk&lt;br /&gt;
 ********************************************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;                // OCEOS header for this application&lt;br /&gt;
#include &amp;quot;tut4.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
volatile U32_t count_task_start = 0;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  int status;&lt;br /&gt;
  /*&lt;br /&gt;
   * Initialise the application configuration and OCEOS&lt;br /&gt;
   *&lt;br /&gt;
   * This application function creates the application configuration&lt;br /&gt;
   * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
   * and enables the system log&lt;br /&gt;
   */&lt;br /&gt;
  if (!application_init()) {&lt;br /&gt;
    //LOG&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  // Create Main task to&lt;br /&gt;
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254&lt;br /&gt;
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority&lt;br /&gt;
                        10,		// threshold, must be in range 1 to task priority&lt;br /&gt;
                        1,				// jobs_max, must be in range 1 to 15&lt;br /&gt;
                        0,// FALSE -&amp;gt; floating point hardware not used by task&lt;br /&gt;
                        1,				// FALSE -&amp;gt; task initially not enabled&lt;br /&gt;
                        fun0,			// main body of task&lt;br /&gt;
                        NULL,		// task end function&lt;br /&gt;
                        0,// time_deadline, must finish no later than this after start, 0 =&amp;gt; ignore&lt;br /&gt;
                        0	// minimum time expected between start requests, 0 =&amp;gt; no restriction&lt;br /&gt;
                        ) != SUCCESSFUL)&lt;br /&gt;
    return 1;&lt;br /&gt;
&lt;br /&gt;
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)&lt;br /&gt;
      != SUCCESSFUL)&lt;br /&gt;
    return 2;&lt;br /&gt;
  /*&lt;br /&gt;
   * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_init_finish();&lt;br /&gt;
  if (SUCCESSFUL != status) {&lt;br /&gt;
    return 3;&lt;br /&gt;
  }   // if&lt;br /&gt;
  /*&lt;br /&gt;
   * Start OCEOS scheduling&lt;br /&gt;
   *&lt;br /&gt;
   * The OCEOS fixed data provides all the information required.&lt;br /&gt;
   *&lt;br /&gt;
   * If a valid task is specified, it is started and passed the pointer.&lt;br /&gt;
   * Otherwise the system is put in sleep mode&lt;br /&gt;
   */&lt;br /&gt;
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS&lt;br /&gt;
  return status;&lt;br /&gt;
}   // main&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Task 0 starting point&lt;br /&gt;
 */&lt;br /&gt;
void fun0(void *ptr) {&lt;br /&gt;
  timer_setup();&lt;br /&gt;
}   // fun0()&lt;br /&gt;
/**&lt;br /&gt;
 * Task 1 starting point;&lt;br /&gt;
 * Triggered from Timer IRQ handler&lt;br /&gt;
 */&lt;br /&gt;
void fun1(void *ptr) {&lt;br /&gt;
  printf(&amp;quot;Task started : %u times \n&amp;quot;, count_task_start);&lt;br /&gt;
  count_task_start++;&lt;br /&gt;
}   // fun1()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorial 5 – Using dataq with timed action ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This exercise introduces the use of dataq with timed action.&amp;lt;/p&amp;gt;&lt;br /&gt;
# Create functions to be used by tasks&lt;br /&gt;
# Create one struct – pointer to these will be placed on queues&lt;br /&gt;
# Set timeout period T&lt;br /&gt;
# Create configuration structure with above configuration values for fields&lt;br /&gt;
# Initialize OCEOS using oceos_init()&lt;br /&gt;
# Create two tasks&lt;br /&gt;
# Create two data queues&lt;br /&gt;
&lt;br /&gt;
For code example see below:&lt;br /&gt;
&lt;br /&gt;
'''''tut5.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                               for ARM/SPARC&lt;br /&gt;
*                              Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                   Application Software Example Header File&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2021, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* File :        asw.h&lt;br /&gt;
* Author:       Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
******************************************************************************&lt;br /&gt;
 */&lt;br /&gt;
#ifndef ASW_H&lt;br /&gt;
#define ASW_H&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;    // OCEOS header&lt;br /&gt;
#include &amp;quot;oceos_timer.h&amp;quot;     &lt;br /&gt;
#include &amp;quot;system_log.h&amp;quot;&lt;br /&gt;
#include &amp;quot;dataq.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define N0 1  // dataq_size&lt;br /&gt;
#define N1 1  // dataq_size&lt;br /&gt;
#define JOBS0 1 // pending q size&lt;br /&gt;
#define JOBS1 1 // pending q size&lt;br /&gt;
#define TIME_OUT 1000000 // timeout&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * APPLICATION FUNCTION DECLARATIONS&lt;br /&gt;
 */&lt;br /&gt;
enum TASK_NAME{&lt;br /&gt;
    t_consumer ,                     // will have task ID 0&lt;br /&gt;
    t_producer,                     // will have task ID 1&lt;br /&gt;
};&lt;br /&gt;
enum DATAQ_NAME{&lt;br /&gt;
  queue_0,                      // will have dataq ID 0&lt;br /&gt;
  queue_1,                      // will have dataq ID 1&lt;br /&gt;
};&lt;br /&gt;
void t_consumer_task(void);&lt;br /&gt;
void t_producer_task(void);&lt;br /&gt;
&lt;br /&gt;
#endif /* ASW_H */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.h'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.h&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
#define INCLUDE_OCEOS_CONFIG_H_&lt;br /&gt;
&lt;br /&gt;
// 1: Includes OCEOS main header file&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 2: Number of Log entries.&lt;br /&gt;
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 3: Number of tasks&lt;br /&gt;
#define NUMBER_OF_TASKS                         2  // 1 to 255&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);&lt;br /&gt;
//    Defaults to number of tasks, as each task should have aa least one job;&lt;br /&gt;
//    If Number of ready Q entries larger that number of total jobs =&amp;gt; defaults to number of total jobs&lt;br /&gt;
#define NUMBER_OF_READYQ_ENTRIES                3&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 5: Number of Mutexes&lt;br /&gt;
#define NUMBER_OF_MUTEXES                       0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 6: Number of Semaphores&lt;br /&gt;
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 7: Number of Data Qs&lt;br /&gt;
#define NUMBER_OF_DATAQS                        2  // 0 to 63&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 8: LOG data array size&lt;br /&gt;
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 9: FIXED data array size&lt;br /&gt;
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 10: DYNAMIC data array size&lt;br /&gt;
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 11: Timed Actions&lt;br /&gt;
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 12: Log entries base 2&lt;br /&gt;
#define CS_LOG_DEF_ENTRIES_BASE2                0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 13: OCEOS stack start Address&lt;br /&gt;
#define OCEOS_STACK_START_ADDRESS               0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
// 14: OCEOS stack end address&lt;br /&gt;
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
/**&lt;br /&gt;
 * Target specific configurations&lt;br /&gt;
 */&lt;br /&gt;
#ifdef __SAM3X8E__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __SAMV71Q21__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef __VA41620__&lt;br /&gt;
#ifndef BSP_SYSFREQ&lt;br /&gt;
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// User defined function to deal with system errors&lt;br /&gt;
void oceos_on_error(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
// User defined function to deal with log 2/3 full&lt;br /&gt;
void oceos_on_full_log(void*);&lt;br /&gt;
//---------------------------------------------------------------------&lt;br /&gt;
extern U32_t log_data[];&lt;br /&gt;
extern U32_t fixed_data[];&lt;br /&gt;
extern U32_t dynamic_data[];&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
/**&lt;br /&gt;
 * Initialize OCEOS with user configurations&lt;br /&gt;
 */&lt;br /&gt;
int application_init(void);&lt;br /&gt;
#endif /* INCLUDE_OCEOS_CONFIG_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''oceos_config.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * app_config.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Configuration Tamplate for OCEOS&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 17 Feb 2020&lt;br /&gt;
 *      Author: Deniss Timofejevs &amp;lt;deniss.timofejevs@ocetechnology.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
#include &amp;quot;oceos_config.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * OCEOS INTERNAL DATA STORAGE&lt;br /&gt;
 *&lt;br /&gt;
 * This application defines arrays to hold OCEOS internal data.&lt;br /&gt;
 * The array sizes are provided by DMON by running &amp;quot;oceos info&amp;quot; command:&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Run DMON command &amp;quot;oceos info&amp;quot; to get size for each array.&amp;lt;/br&amp;gt;&lt;br /&gt;
 *  *Update array sizes below&lt;br /&gt;
 */&lt;br /&gt;
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment&lt;br /&gt;
&lt;br /&gt;
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];&lt;br /&gt;
&lt;br /&gt;
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO&lt;br /&gt;
&lt;br /&gt;
static BOOLE_t log_full_was_called = FALSE;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Set up the application configuration structure and pass it to oceos_init&lt;br /&gt;
 * (done this way the memory used for the structure is returned automatically)&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int application_init(){&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Create the application configuration structure&lt;br /&gt;
     */&lt;br /&gt;
    struct application_configuration           app_config = {0};&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Fill in the application parameters&lt;br /&gt;
     */&lt;br /&gt;
    app_config.log_address                   = (adrs_t)log_data;              // required&lt;br /&gt;
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required&lt;br /&gt;
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required&lt;br /&gt;
&lt;br /&gt;
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 =&amp;gt; no check&lt;br /&gt;
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 =&amp;gt; no check&lt;br /&gt;
&lt;br /&gt;
    app_config.system_error_function         = &amp;amp;oceos_on_error;               // NULL =&amp;gt; ignore&lt;br /&gt;
    app_config.log_full_function             = &amp;amp;oceos_on_full_log;            // NULL =&amp;gt; ignore&lt;br /&gt;
&lt;br /&gt;
    // used in setting up system log and fixed data array&lt;br /&gt;
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 =&amp;gt; use default&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // &amp;gt;= 1&lt;br /&gt;
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 =&amp;gt; calculate size&lt;br /&gt;
&lt;br /&gt;
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;&lt;br /&gt;
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;&lt;br /&gt;
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;&lt;br /&gt;
&lt;br /&gt;
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;&lt;br /&gt;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;&lt;br /&gt;
    app_config.use_oceos_system_time         = TRUE;&lt;br /&gt;
&lt;br /&gt;
    // initialise OCEOS&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    status = oceos_init(app_config);&lt;br /&gt;
    assert(SUCCESSFUL == status);&lt;br /&gt;
&lt;br /&gt;
    if (SUCCESSFUL == status) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\n oceos_init failure\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }   // else&lt;br /&gt;
}   // application_init()&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system error;&lt;br /&gt;
 * Comment it out if not used and set field system_error_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_error(void* ptr) {&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User to implement in case of system log is 2/3 full;&lt;br /&gt;
 * Comment it out if not used and set field log_full_function in app_config to NULL&lt;br /&gt;
 */&lt;br /&gt;
void oceos_on_full_log(void* ptr){&lt;br /&gt;
  log_full_was_called = TRUE;&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
'''''tut5.c'''''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*                                   OCEOS&lt;br /&gt;
*                        Real-Time Operating System&lt;br /&gt;
*                              for ARM/SPARC&lt;br /&gt;
*                             Microcontroller&lt;br /&gt;
*&lt;br /&gt;
*                       Application Software Example&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
*                    (c) Copyright 2022, O.C.E. Technology&lt;br /&gt;
*                             All Rights Reserved&lt;br /&gt;
*&lt;br /&gt;
* Author:       jfk&lt;br /&gt;
*&lt;br /&gt;
* Purpose                : The test here involves creating two tasks with different priorities, &lt;br /&gt;
*						   and two data queues with timed action implimentation.&lt;br /&gt;
*&lt;br /&gt;
******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
/* N.B.  Application header is included first */&lt;br /&gt;
#include &amp;quot;tut5.h&amp;quot;                        // application header&lt;br /&gt;
&lt;br /&gt;
struct data {&lt;br /&gt;
  int status;&lt;br /&gt;
  char *message;&lt;br /&gt;
} test_data = {&lt;br /&gt;
    1,&lt;br /&gt;
    &amp;quot;Test Data&amp;quot;,&lt;br /&gt;
};&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Initialise the application configuration and OCEOS&lt;br /&gt;
     *&lt;br /&gt;
     * This application function creates the application configuration&lt;br /&gt;
     * and passes it to oceos_init(), which initialises the fixed data&lt;br /&gt;
     * and enables the system log&lt;br /&gt;
     */&lt;br /&gt;
    if ( !application_init()) {&lt;br /&gt;
        //LOG&lt;br /&gt;
        printf(&amp;quot;\nProblem\n&amp;quot;);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    enum DIRECTIVE_STATUS status;&lt;br /&gt;
    // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_consumer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
	&lt;br /&gt;
    // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0&lt;br /&gt;
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);&lt;br /&gt;
	  if(SUCCESSFUL != status){&lt;br /&gt;
        // LOG&lt;br /&gt;
        printf(&amp;quot;\nAbandoning, problem creating task t_producer, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
        return -1;&lt;br /&gt;
      }   // if&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n Tasks created\n&amp;quot;);&lt;br /&gt;
    // no counting semaphores, data queues or user defined traps&lt;br /&gt;
&lt;br /&gt;
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);&lt;br /&gt;
     if(SUCCESSFUL != status){&lt;br /&gt;
        printf(&amp;quot;\nProblem creating dataq queue_0, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     }   // if&lt;br /&gt;
	&lt;br /&gt;
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE&lt;br /&gt;
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);&lt;br /&gt;
      if(SUCCESSFUL != status){&lt;br /&gt;
       printf(&amp;quot;\nProblem creating dataq queue_1, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
      }   // if&lt;br /&gt;
    /*&lt;br /&gt;
     * Finish initialising OCEOS and setting up the fixed data&lt;br /&gt;
     */&lt;br /&gt;
    status = oceos_init_finish();&lt;br /&gt;
    if(SUCCESSFUL != status){&lt;br /&gt;
     printf(&amp;quot;\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n&amp;quot;, status);&lt;br /&gt;
     return -1;&lt;br /&gt;
    }   // if&lt;br /&gt;
    //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
    status = oceos_start(fixed_data, t_producer, NULL);&lt;br /&gt;
&lt;br /&gt;
    return status;                          // returned as an integer&lt;br /&gt;
&lt;br /&gt;
}   // function waits for specific time interval&lt;br /&gt;
void test_wait(U32_t interval) {&lt;br /&gt;
  volatile U32_t start_time = oceos_time_sys_get32();&lt;br /&gt;
  volatile U32_t cur_time = 0;&lt;br /&gt;
  while(1) {&lt;br /&gt;
      cur_time = oceos_time_sys_get32();&lt;br /&gt;
      if ((cur_time - start_time) &amp;gt;= interval ) {&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * Tasks&lt;br /&gt;
 */&lt;br /&gt;
void t_consumer_task() {&lt;br /&gt;
  static int case_number = 0;&lt;br /&gt;
  if (case_number == 0) {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries is 0&lt;br /&gt;
      // c.  Check: queue_1 entries is 0&lt;br /&gt;
      printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  &lt;br /&gt;
      // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
      oceos_dataq_read_restart_timeout(queue_0, 0);&lt;br /&gt;
  } else if (case_number == 1){&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
      // Check:  Task 0 has started, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 1&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 6) Action: Task 0 does read_restart on queue 0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: non-null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_0 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 7)    Action: Task 0 writes this pointer to queue_1&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 1&lt;br /&gt;
	   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
       printf(&amp;quot;\nDataq write was not succesful\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
      // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read restart timeout returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
  } else {&lt;br /&gt;
      case_number++;&lt;br /&gt;
      // 10)   Action: Task 1 loops for at least twice timeout period T&lt;br /&gt;
      // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
      // a.  Check: entry message from Task 0&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer was started\n&amp;quot;);&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 11)    Action: Task 0 does read_continue on queue_0&lt;br /&gt;
      // Check:  Task 0 has succeeded&lt;br /&gt;
      // a.  Check: null pointer returned&lt;br /&gt;
      // b.  Check: queue_0 entries count is 0&lt;br /&gt;
      // c.  Check: queue_1 entries count is 0&lt;br /&gt;
	   if(oceos_dataq_read_continue(queue_0) != NULL){&lt;br /&gt;
       printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
&lt;br /&gt;
      // 12)   Action: Task 0 exits&lt;br /&gt;
      // Check:  Task 0 exit message&lt;br /&gt;
      // a.  Check: queue_0 entries count is 0&lt;br /&gt;
      // b.  Check: queue_1 entries count is 0&lt;br /&gt;
       printf(&amp;quot;t_consumer is exiting\n&amp;quot;);&lt;br /&gt;
       if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
	   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
       printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
       }   // if&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
}//END  t_consumer_task&lt;br /&gt;
&lt;br /&gt;
void t_producer_task() {&lt;br /&gt;
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer&lt;br /&gt;
  // Check: Task 1 has started&lt;br /&gt;
  // a.  Check: Starting message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_0 capacity is as created&lt;br /&gt;
  // d.  Check: queue_1 entries count is 0&lt;br /&gt;
  // e.  Check: queue_1 capacity is as created&lt;br /&gt;
  printf(&amp;quot;t_producer was started\n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 2)  Action: Task 1 attempts to start Task 0&lt;br /&gt;
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nFailed starting task t_consumer\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 3) Action: Task 0 does read_restart on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queue_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 4) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:   null pointer returned&lt;br /&gt;
   if(oceos_dataq_read_continue(queue_1) != NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read continue returned not null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 5) Action: Task 1 writes pointer to struct to queue_0&lt;br /&gt;
   if(oceos_dataq_write(queue_0, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 8) Action: Task 0 does read_restart with timeout on queue_0&lt;br /&gt;
  // Check:  Task 0 exits as queues_0 is empty&lt;br /&gt;
  // Check:  Task 1 continues&lt;br /&gt;
  // a.  Check: continue message from Task 1&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 1&lt;br /&gt;
   printf(&amp;quot;t_producer continues \n&amp;quot;);&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 9) Action: Task 1 does read_continue on queue_1&lt;br /&gt;
  // Check:  Non-null pointer returned&lt;br /&gt;
  // a.  Check: pointer to same struct&lt;br /&gt;
  // b.  Check: queue_0 entries count is 0&lt;br /&gt;
  // c.  Check: queue_1 entries count is 0&lt;br /&gt;
   struct data *temp_data = oceos_dataq_read_continue(queue_1);&lt;br /&gt;
   if(temp_data == NULL){&lt;br /&gt;
   printf(&amp;quot;\ntemp_data is null\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(test_data.message != temp_data-&amp;gt;message){&lt;br /&gt;
   printf(&amp;quot;\npointer not to same struct\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_0)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_0 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 10)   Action: Task 1 loops for at least three timeout period&lt;br /&gt;
  // Check:  Task 0 restarts on timeout, pre-empting Task 1&lt;br /&gt;
  test_wait(TIME_OUT * 3);&lt;br /&gt;
&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Task 1 does read restart on queue_1&lt;br /&gt;
   if(oceos_dataq_read_restart(queue_1) == NULL){&lt;br /&gt;
   printf(&amp;quot;\nDataq read restart failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  //Task 1 writes pointer to struct on queue_1&lt;br /&gt;
   if(oceos_dataq_write(queue_1, &amp;amp;test_data) != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nDataq write failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 1){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 1\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data q clear&lt;br /&gt;
   if(oceos_dataq_clear(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq clear failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  &lt;br /&gt;
  // Data q size check&lt;br /&gt;
   if(oceos_dataq_get_size(queue_1)!= 0){&lt;br /&gt;
   printf(&amp;quot;\nData queue_1 entries is not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
  // Data pending q size check&lt;br /&gt;
   if(oceos_dataq_penq_get_size(queue_1) != 0){&lt;br /&gt;
   printf(&amp;quot;\nDataq pending queue not equal to 0\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
&lt;br /&gt;
  // 14)   Action: Task 1 terminates&lt;br /&gt;
   // Check:  Task 1 exit message&lt;br /&gt;
   printf(&amp;quot;t_producer is exiting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // 15) Action: CPU placed in sleep mode&lt;br /&gt;
  // Check:  Sleep mode starting message&lt;br /&gt;
   if(oceos_exit() != SUCCESSFUL){&lt;br /&gt;
   printf(&amp;quot;\nOceos exiting failed\n&amp;quot;);&lt;br /&gt;
   }   // if&lt;br /&gt;
   &lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;color:#0000ff&amp;quot;&amp;gt;'''Drivers Porting Example'''&amp;lt;/span&amp;gt;=&lt;br /&gt;
TODO How to port project from other ROTS&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
</feed>