Salvo User Manual
User Manual:
Open the PDF directly: View PDF
Page Count: 529 [warning: Documents this large are best viewed by clicking the View PDF Link!]
- Quick Start Guide
- Contact Information & Technical Support
- Contents
- Figures
- Listings
- Tables
- Release Notes
- Supported Targets and Compilers
- Preface
- Chapter 1 • Introduction
- Chapter 2 • RTOS Fundamentals
- Introduction
- Basic Terms
- Foreground / Background Systems
- Reentrancy
- Resources
- Multitasking and Context Switching
- Tasks and Interrupts
- Preemptive vs. Cooperative Scheduling
- More on Multitasking
- Events and Intertask Communications
- Summary of Task and Event Interaction
- Conflicts
- RTOS Performance
- A Real-World Example
- Chapter 3 • Installation
- Chapter 4 • Tutorial
- Chapter 5 • Configuration
- Introduction
- The Salvo Build Process
- Configuration Option Overview
- Configuration Options for all Distributions
- OSCOMPILER: Identify Compiler in Use
- OSEVENTS: Set Maximum Number of Events
- OSEVENT_FLAGS: Set Maximum Number of Event Flags
- OSLIBRARY_CONFIG: Specify Precompiled Library Configuration
- OSLIBRARY_GLOBALS: Specify Memory Type for Global Salvo Objects in Precompiled Library
- OSLIBRARY_OPTION: Specify Precompiled Library Option
- OSLIBRARY_TYPE: Specify Precompiled Library Type
- OSLIBRARY_VARIANT: Specify Precompiled Library Variant
- OSMESSAGE_QUEUES: Set Maximum Number of Message Queues
- OSTARGET: Identify Target Processor
- OSTASKS: Set Maximum Number of Tasks and Cyclic Timers
- OSUSE_LIBRARY: Use Precompiled Library
- Configuration Options for Source Code Distributions
- OSBIG_SEMAPHORES: Use 16-bit Semaphores
- OSBYTES_OF_COUNTS: Set Size of Counters
- OSBYTES_OF_DELAYS: Set Length of Delays
- OSBYTES_OF_EVENT_FLAGS: Set Size of Event Flags
- OSBYTES_OF_TICKS: Set Maximum System Tick Count
- OSCALL_OSCREATEEVENT: Manage Interrupts when Creating Events
- OSCALL_OSGETPRIOTASK: Manage Interrupts when Returning a Task's Priority
- OSCALL_OSGETSTATETASK: Manage Interrupts when Returning a Task's State
- OSCALL_OSMSGQCOUNT: Manage Interrupts when Returning Number of Messages in Message Queue
- OSCALL_OSMSGQEMPTY: Manage Interrupts when Checking if Message Queue is Empty
- OSCALL_OSRETURNEVENT: Manage Interrupts when Reading and/or Trying Events
- OSCALL_OSSIGNALEVENT: Manage Interrupts when Signaling Events and Manipulating Event Flags
- OSCALL_OSSTARTTASK: Manage Interrupts when Starting Tasks
- OSCLEAR_GLOBALS: Explicitly Clear all Global Parameters
- OSCLEAR_UNUSED_POINTERS: Reset Unused Tcb and Ecb Pointers
- OSCOLLECT_LOST_TICKS: Configure Timer System For Maximum Versatility
- OSCOMBINE_EVENT_SERVICES: Combine Common Event Service Code
- OSCTXSW_METHOD: Identify Context-Switching Methodology in Use
- OSCUSTOM_LIBRARY_CONFIG: Select Custom Library Configuration File
- OSDISABLE_ERROR_CHECKING: Disable Runtime Error Checking
- OSDISABLE_FAST_SCHEDULING: Configure Round-Robin Scheduling
- OSDISABLE_TASK_PRIORITIES: Force All Tasks to Same Priority
- OSENABLE_BINARY_SEMAPHORES: Enable Support for Binary Semaphores
- OSENABLE_BOUNDS_CHECKING: Enable Runtime Pointer Bounds Checking
- OSENABLE_CYCLIC_TIMERS: Enable Cyclic Timers
- OSENABLE_EVENT_FLAGS: Enable Support for Event Flags
- OSENABLE_EVENT_READING: Enable Support for Event Reading
- OSENABLE_EVENT_TRYING: Enable Support for Event Trying
- OSENABLE_FAST_SIGNALING: Enable Fast Event Signaling
- OSENABLE_IDLE_COUNTER: Track Scheduler Idling
- OSENABLE_IDLING_HOOK: Call a User Function when Idling
- OSENABLE_MESSAGES: Enable Support for Messages
- OSENABLE_MESSAGE_QUEUES: Enable Support for Message Queues
- OSENABLE_OSSCHED_DISPATCH_HOOK: Call User Function Inside Scheduler
- OSENABLE_OSSCHED_ENTRY_HOOK: Call User Function Inside Scheduler
- OSENABLE_OSSCHED_RETURN_HOOK: Call User Function Inside Scheduler
- OSENABLE_SEMAPHORES: Enable Support for Semaphores
- OSENABLE_STACK_CHECKING: Monitor Call ... Return Stack Depth
- OSENABLE_TCBEXT0|1|2|3|4|5: Enable Tcb Extensions
- OSENABLE_TIMEOUTS: Enable Support for Timeouts
- OSGATHER_STATISTICS: Collect Run-time Statistics
- OSINTERRUPT_LEVEL: Specify Interrupt Level for Interrupt-callable Services
- OSLOC_ALL: Storage Type for All Salvo Objects
- OSLOC_COUNT: Storage Type for Counters
- OSLOC_CTCB: Storage Type for Current Task Control Block Pointer
- OSLOC_DEPTH: Storage Type for Stack Depth Counters
- OSLOC_ECB: Storage Type for Event Control Blocks and Queue Pointers
- OSLOC_EFCB: Storage Type for Event Flag Control Blocks
- OSLOC_ERR: Storage Type for Error Counters
- OSLOC_GLSTAT: Storage Type for Global Status Bits
- OSLOC_LOGMSG: Storage Type for Log Message String
- OSLOC_LOST_TICK: Storage Type for Lost Ticks
- OSLOC_MQCB: Storage Type for Message Queue Control Blocks
- OSLOC_MSGQ: Storage Type for Message Queues
- OSLOC_PS: Storage Type for Timer Prescalar
- OSLOC_TCB: Storage Type for Task Control Blocks
- OSLOC_SIGQ: Storage Type for Signaled Events Queue Pointers
- OSLOC_TICK: Storage Type for System Tick Counter
- OSLOGGING: Log Runtime Errors and Warnings
- OSLOG_MESSAGES: Configure Runtime Logging Messages
- OS_MESSAGE_TYPE: Configure Message Pointers
- OSMPLAB_C18_LOC_ALL_NEAR: Locate all Salvo Objects in Access Bank (MPLAB-C18 Only)
- OSOPTIMIZE_FOR_SPEED: Optimize for Code Size or Speed
- OSPIC18_INTERRUPT_MASK: Configure PIC18 Interrupt Mode
- OSRPT_HIDE_INVALID_POINTERS: OSRpt() Won't Display Invalid Pointers
- OSRPT_SHOW_ONLY_ACTIVE: OSRpt() Displays Only Active Task and Event Data
- OSRPT_SHOW_TOTAL_DELAY: OSRpt() Shows the Total Delay in the Delay Queue
- OSRTNADDR_OFFSET: Offset (in bytes) for Context-Switching Saved Return Address
- OSSCHED_RETURN_LABEL(): Define Label within OSSched()
- OSSET_LIMITS: Limit Number of Runtime Salvo Objects
- OSSPEEDUP_QUEUEING: Speed Up Queue Operations
- OSTIMER_PRESCALAR: Configure Prescalar for OSTimer()
- OSTYPE_TCBEXT0|1|2|3|4|5: Set Tcb Extension Type
- OSUSE_CHAR_SIZED_BITFIELDS: Pack Bitfields into Chars
- OSUSE_EVENT_TYPES: Check for Event Types at Runtime
- OSUSE_INLINE_OSSCHED: Reduce Task Call…Return Stack Depth
- OSUSE_INLINE_OSTIMER: Eliminate OSTimer() Call…Return Stack Usage
- OSUSE_INSELIG_MACRO: Reduce Salvo's Call Depth
- OSUSE_MEMSET: Use memset() (if available)
- Organization
- Choosing the Right Options for your Application
- Predefined Configuration Constants
- Obsolete Configuration Parameters
- Chapter 6 • Frequently Asked Questions (FAQ)
- General
- What is Salvo?
- Is there a shareware / freeware / open source version of Salvo?
- Just how small is Salvo?
- Why should I use Salvo?
- What should I consider Salvo Pro over Salvo LE?
- What can I do with Salvo?
- What kind of RTOS is Salvo?
- What are Salvo's minimum requirements?
- What kind of processors can Salvo applications run on?
- My compiler doesn't implement a stack. It allocates variables using a static overlay model. Can it be used with Salvo?
- How many tasks and events does Salvo support?
- How many priority levels does Salvo support?
- What kind of events does Salvo support?
- Is Salvo Y2K compliant?
- Where did Salvo come from?
- Getting Started
- Performance
- Memory
- How much will Salvo add to my application's ROM and RAM usage?
- How much RAM will an application built with the libraries use?
- Do I need to worry about running out of memory?
- If I define a task or event but never use it, is it costing me RAM?
- How much call ... return stack depth does Salvo use?
- Why must I use pointers when working with tasks? Why can't I use explicit task IDs?
- How can I avoid re-initializing Salvo's variables when I wake up from sleep on a PIC12C509 PICmicro MCU?
- Libraries
- What kinds of libraries does Salvo include?
- What's in each Salvo library?
- Why are there so many libraries?
- Should I use the libraries or the source code when building my application?
- What's the difference between the freeware and standard Salvo libraries?
- My library-based application is using more RAM than I can account for. Why?
- I'm using a library. Why does my application use more RAM than one compiled directly from source files?
- I'm using a freeware library and I get the message "#error: OSXYZ exceeds library limit – aborting." Why?
- Why can't I alter the functionality of a library by adding configuration options to my salvocfg.h?
- The libraries are very large – much larger than the ROM size of my target processor. Won't that affect my application?
- I'm using a library. Can I change the bank where Salvo variables are located?
- Configuration
- I'm overwhelmed by all the configuration options. Where should I start?
- Do I have to use all of Salvo's functionality?
- What file(s) do I include in my main.c?
- What is the purpose of OSENABLE_˜SEMAPHORES and similar configuration options?
- Can I collect run-time statistics with Salvo?
- How can I clear my processor's watchdog timer with Salvo?
- I enabled timeouts and my RAM and ROM grew substantially– why?
- Timer and Timing
- Do I have to install the timer?
- How do I install the timer?
- I added the timer to my ISR and now my ISR is huge and slow. What should I do?
- How do I pick a tick rate for Salvo?
- How do I use the timer prescalar?
- I enabled the prescalar and set it to 1 but it didn't make any difference. Why?
- What is the accuracy of the system timer?
- What is Salvo's interrupt latency?
- What if I need to specify delays larger than 8 bits of ticks?
- How can I achieve very long delays via Salvo? Can I do that and still keep task memory to a minimum?
- Can I specify a timeout when waiting for an event?
- Does Salvo provide functions to obtain elapsed time?
- How do I choose the right value for OSBYTES_OF_TICKS?
- My processor has no interrupts. Can I still use Salvo's timer services?
- Context Switching
- Tasks & Events
- What are taskIDs?
- Does it matter which taskID I assign to a particular task?
- Is there an idle task in Salvo?
- How can I monitor the tasks in my application?
- What exactly happens in the scheduler?
- What about reentrant code and Salvo?
- What are "implicit" and "explicit" OS task functions?
- How do I setup an infinite loop in a task?
- Why must tasks use static local variables?
- Doesn't using static local variables take more memory than with other RTOSes?
- Can tasks share the same priority?
- Can I have multiple instances of the same task?
- Does the order in which I start tasks matter?
- How can I reduce code size when starting tasks?
- What is the difference between a delayed task and a waiting task?
- Can I create a task to immediately wait an event?
- I started a task but it never ran. Why?
- What happens if I forget to loop in my task?
- Why did my low-priority run-time tasks start running before my high-priority startup task completed?
- When I signaled a waiting task, it took much longer than the context switching time to run. Why?
- Can I destroy a task and (re-) create a new one in its place?
- Can more than one task wait on an event?
- Does Salvo preserve the order in which events occur?
- Can a task wait on more than one event at a time?
- How can I implement event flags?
- What happens when a task times out waiting for an event?
- Why is my high-priority task stuck waiting, while other low-priority tasks are running?
- When an event occurs and there are tasks waiting for it, which task(s) become eligible?
- How can I tell if a task timed out waiting for an event?
- Can I create an event from inside a task?
- What kind of information can I pass to a task via a message?
- My application uses messages and binary sema˜phores. Is there any way to make the Salvo code smaller?
- Why did RAM requirements increase substantially when I enabled message queues?
- Can I signal an event from outside a task?
- When I signal a message that has more than one task waiting for it, why does only one task become eligible?
- I'm using a message event to pass a character variable to a waiting task, but I don't get the right data when I dereference the pointer. What's going on?
- What happens when there are no tasks in the eligible queue?
- In what order do messages leave a message queue?
- What happens if an event is signaled before any task starts to wait it? Will the event get lost or it will be processed after task starts to wait it?
- What happens if an event is signaled several times before waiting task gets a chance to run and process that event? Will the last one signal be processed and previous lost? Or the first will be processed and the following signals lost?
- What is more important to create first, an event or the task that waits it? Does the order of creation matter?
- What if I don't need one event anymore and want to use its slot for another event? Can I destroy event?
- Can I use messages or message queues to pass raw data between tasks?
- How can I test if there's room for additional messages in a message queue without signaling the message queue?
- Interrupts
- Why does Salvo disable all interrupts during a critical section of code?
- I'm concerned about interrupt latency. Can I modify Salvo to disable only certain interrupts during critical sections of code?
- How big are the Salvo functions I might call from within an interrupt?
- Why did my interrupt service routine grow and become slower when I added a call to OSTimer()?
- My application can't afford the overhead of signaling from an ISR. How can I get around this problem?
- Building Projects
- Miscellaneous
- General
- Chapter 7 • Reference
- Run-Time Architecture
- User Services
- OS_Delay(): Delay the Current Task and Context-switch
- OS_DelayTS(): Delay the Current Task Relative to its Timestamp and Context-switch
- OS_Destroy(): Destroy the Current Task and Context-switch
- OS_Replace(): Replace the Current Task and Context-switch
- OS_SetPrio(): Change the Current Task's Priority and Context-switch
- OS_Stop(): Stop the Current Task and Context-switch
- OS_WaitBinSem(): Context-switch and Wait the Current Task on a Binary Semaphore
- OS_WaitEFlag(): Context-switch and Wait the Current Task on an Event Flag
- OS_WaitMsg(): Context-switch and Wait the Current Task on a Message
- OS_WaitMsgQ(): Context-switch and Wait the Current Task on a Message Queue
- OS_WaitSem(): Context-switch and Wait the Current Task on a Semaphore
- OS_Yield(): Context-switch
- OSClrEFlag(): Clear Event Flag Bit(s)
- OSCreateBinSem(): Create a Binary Semaphore
- OSCreateCycTmr(): Create a Cyclic Timer
- OSCreateEFlag(): Create an Event Flag
- OSCreateMsg(): Create a Message
- OSCreateMsgQ(): Create a Message Queue
- OSCreateSem(): Create a Semaphore
- OSCreateTask(): Create and Start a Task
- OSDestroyCycTmr(): Destroy a Cyclic Timer
- OSDestroyTask(): Destroy a Task
- OSGetPrio(): Return the Current Task's Priority
- OSGetPrioTask(): Return the Specified Task's Priority
- OSGetState(): Return the Current Task's State
- OSGetStateTask(): Return the Specified Task's State
- OSGetTicks(): Return the System Timer
- OSGetTS(): Return the Current Task's Timestamp
- OSInit(): Prepare for Multitasking
- OSMsgQCount(): Return Number of Messages in Message Queue
- OSMsgQEmpty(): Check for Available Space in Message Queue
- OSReadBinSem(): Obtain a Binary Semaphore Unconditionally
- OSReadEFlag(): Obtain an Event Flag Unconditionally
- OSReadMsg():Obtain a Message's Message Pointer Unconditionally
- OSReadMsgQ(): Obtain a Message Queue's Message Pointer Unconditionally
- OSReadSem(): Obtain a Semaphore Unconditionally
- OSResetCycTmr(): Reset a Cyclic Timer
- OSRpt(): Display the Status of all Tasks, Events, Queues and Counters
- OSSched(): Run the Highest-Priority Eligible Task
- OSSetCycTmrPeriod(): Set a Cyclic Timer's Period
- OSSetEFlag(): Set Event Flag Bit(s)
- OSSetPrio(): Change the Current Task's Priority
- OSSetPrioTask(): Change a Task's Priority
- OSSetTicks(): Initialize the System Timer
- OSSetTS(): Initialize the Current Task's Timestamp
- OSSignalBinSem(): Signal a Binary Semaphore
- OSSignalMsg(): Send a Message
- OSSignalMsgQ(): Send a Message via a Message Queue
- OSSignalSem(): Signal a Semaphore
- OSStartCycTmr(): Start a Cyclic Timer
- OSStartTask(): Make a Task Eligible To Run
- OSStopCycTmr(): Stop a Cyclic Timer
- OSStopTask(): Stop a Task
- OSSyncTS(): Synchronize the Current Task's Timestamp
- OSTimer(): Run the Timer
- OSTryBinSem(): Obtain a Binary Semaphore if Available
- OSTryMsg(): Obtain a Message if Available
- OSTryMsgQ(): Obtain a Message from a Message Queue if Available
- OSTrySem(): Obtain a Semaphore if Available
- Additional User Services
- OSAnyEligibleTasks (): Check for Eligible Tasks
- OScTcbExt0|1|2|3|4|5, OStcbExt0|1|2|3|4|5(): Return a Tcb Extension
- OSCycTmrRunning(): Check Cyclic Timer for Running
- OSProtect(), OSUnprotect(): Protect Services Against Corruption by ISR
- OSTaskStopped(): Check whether Task has Stopped
- OSTimedOut(): Check for Timeout
- OSVersion(), OSVERSION: Return Version as Integer
- User Macros
- User-Defined Services
- Return Codes
- Salvo Defined Types
- Salvo Variables
- Salvo Source Code
- Locations of Salvo Functions
- Abbreviations Used by Salvo
- Chapter 8 • Libraries
- Chapter 9 • Performance
- Chapter 10 • Porting
- Chapter 11 • Tips, Tricks and Troubleshooting
- Introduction
- Compile-Time Troubleshooting
- I'm just starting, and I'm getting lots of errors.
- My compiler can't find salvo.h.
- My compiler can't find salvocfg.h.
- My compiler can't find certain target-specific header files.
- My compiler can't locate a particular Salvo service.
- My compiler has issued an "undefined symbol" error for a context-switching label that I've defined properly.
- My compiler is saying something about OSIdlingHook.
- My compiler has no command-line tools. Can I still build a library?
- Run-Time Troubleshooting
- Compiler Issues
- Where can I get a free C compiler?
- Where can I get a free make utility?
- Where can I get a Linux/Unix-like shell for my Windows PC?
- My compiler behaves strangely when I'm compiling from the DOS command line, e.g. "This program has performed an illegal operation and will be terminated."
- My compiler is issuing redeclaration errors when I compile my program with Salvo's source files.
- HI-TECH PICC Compiler
- Running HPDPIC under Windows 2000 Pro
- Setting PICC Error/Warning Format under Windows 2000 Pro
- Linker reports fixup errors
- Placing variables in RAM
- Link errors when working with libraries
- Avoiding absolute file pathnames
- Compiled code doesn't work
- PIC17CXXX pointer passing bugs
- While() statements and context switches
- Library generation in HPDPIC
- Problems banking Salvo variables on 12-bit devices
- Working with Salvo messages
- Adding OSTimer() to an Interrupt Service Routine
- Using the interrupt_level pragma
- HI-TECH V8C Compiler
- HI-TECH 8051C Compiler
- IAR PICC Compiler
- Mix Power C Compiler
- Metrowerks CodeWarrior Compiler
- Microchip MPLAB
- Controlling the Size of your Application
- Working with Message Pointers
- Appendix A • Recommended Reading
- Appendix B • Other Resources
- Appendix C • File and Program Descriptions
- Index
- Notes