%$Header: /home/dashley/cvsrep/e3ft_gpl01/e3ft_gpl01/dtaipubs/cron/2006/phdtopicpropa/phdtopicpropa.tex,v 1.20 2006/03/27 00:10:30 dashley Exp $ \documentclass[letterpaper,10pt,titlepage]{article} % %\pagestyle{headings} % \usepackage{amsmath} \usepackage{amsfonts} \usepackage{amssymb} \usepackage[ansinew]{inputenc} \usepackage[OT1]{fontenc} \usepackage{graphicx} % \begin{document} %----------------------------------------------------------------------------------- \title{Ph.D. Topic Proposal} \author{\vspace{2cm}\\David T. Ashley\\\texttt{dta@e3ft.com}\\\vspace{2cm}} \date{\vspace*{8mm}\small{Version Control $ $Revision: 1.20 $ $ \\ Version Control $ $Date: 2006/03/27 00:10:30 $ $ (UTC) \\ $ $RCSfile: phdtopicpropa.tex,v $ $ \\ \LaTeX{} Compilation Date: \today{}}} \maketitle %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \begin{abstract} This document describes my Ph.D. research interests and provides supporting information. The interests (described in \S{}\ref{srin0}) revolve around the mathematical basis of timed automata systems and code generation from timed automata models. \end{abstract} \clearpage{} \pagenumbering{roman} %No page number on table of contents. \tableofcontents{} \clearpage{} \listoffigures \clearpage{} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %Force the page number to 1. We don't want to number the table of contents %page. % \setcounter{page}{1} \pagenumbering{arabic} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{The Timed Automata Framework} \label{staf0} The framework of timed automata isn't commonplace in electrical engineering, so this section provides a description. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The Framework} \label{staf0:stfw0} The formal framework of timed automata consists of systems of automatons, each with discrete states, transitions, and timers that can be reset to zero on transitions. The framework includes synchronization mechanisms between automatons (i.e. automatons may interact in well-defined ways)\@. Synchronization mechanisms consist of ``soft'' synchronization mechanisms and ``hard'' synchronization mechanisms. \begin{itemize} \item \emph{Soft} synchronization mechanisms involve one automaton having transition functions that involve the discrete state or timers of another automaton. \item \emph{Hard} synchronization mechanisms involve events. The semantics of an event require two or more automatons to make corresponding transitions at exactly the same time. \end{itemize} The details of the framework aren't especially important, and there are several variations on the framework\footnote{Variations include substates, differences in the semantics of events, and dynamics that go beyond $\dot{t} = 1$ (i.e. hybrid systems).} that don't change the essential properties. The essential properties of the framework (that don't change with the variations) are: \begin{itemize} \item A system of timed automata that interact via synchronization mechanisms can be mathematically combined into a single larger automaton with a single discrete state space. \item There is some symbolic method of reasoning about what values timers can attain in each discrete state (polytopes, DBMs, etc.). \item The symbolic reasoning about timer values often allows reasoning about properties of the system (reachability, liveness, etc.). \end{itemize} Timed automata are recognizeable to any embedded software engineer as ``state machines''. A typical automotive embedded system consists of many features and software components involving discrete state. For example, software to control an automobile drivetrain with features like automatic 4-wheel drive as well as sensor and actuator failure modes tends to have a very large discrete space. As a contrived example of a system of timed automata, consider the problem of controlling a drawbridge with one motor and two limit switches so that it goes up and down with period $K_D + K_U$ (Fig. \ref{fig:staf0:stfw0:000}). \begin{figure} \centering \includegraphics[width=4.0in]{system01.eps} \caption{Example Timed Automata System (Drawbridge Control)} \label{fig:staf0:stfw0:000} \end{figure} Assume that when raising the drawbridge, it is adequate to energize the motor until the limit switch $U$ closes. However, when closing the drawbridge, it is necessary to energize the motor for time $K_L$ beyond when the limit switch $D$ closes (the $B_{DOWNLOCK}$ state in Fig. \ref{fig:staf0:stfw0:01}). One way to design such a system is with two automata (Fig. \ref{fig:staf0:stfw0:00} and Fig. \ref{fig:staf0:stfw0:01}) interacting via synchronization mechnisms. The automaton of Fig. \ref{fig:staf0:stfw0:00} alternates between two states with period $K_D + K_U$. At any point in time, the state of this automaton indicates whether the drawbridge should be down or up. \begin{figure} \centering \includegraphics[height=2.5in]{exta01.eps} \caption{Example Timed Automaton (Drawbridge Target Position Determination)} \label{fig:staf0:stfw0:00} \end{figure} The automaton of Fig. \ref{fig:staf0:stfw0:01} directly determines the energization of the bridge motor as a function of the limit switches $D$ and $U$, the discrete state of the automaton of Fig. \ref{fig:staf0:stfw0:00}, and time. In the $B_{IDLE}$ state, the motor is deenergized. In the $B_{UP}$ state, the motor is energized to move the drawbridge up. In the $B_{DOWN}$ and $B_{DOWNLOCK}$ states, the motor is energized to move the drawbridge down. \begin{figure} \centering \includegraphics[width=4.6in]{exta02.eps} \caption{Example Timed Automaton (Drawbridge Motor Control)} \label{fig:staf0:stfw0:01} \end{figure} Mathematically, the automata of Figs. \ref{fig:staf0:stfw0:00} and \ref{fig:staf0:stfw0:01} can be combined to give the automaton of Fig. \ref{fig:staf0:stfw0:02}\@. This mathematical operation is sometimes called the ``shuffle'' operation. \begin{figure} \centering \includegraphics[width=4.6in]{exta03.eps} \caption{Example Timed Automaton (Shuffle of Fig. \ref{fig:staf0:stfw0:00} and Fig. \ref{fig:staf0:stfw0:01})} \label{fig:staf0:stfw0:02} \end{figure} In Fig. \ref{fig:staf0:stfw0:02}, each of the eight discrete states corresponds to one discrete state from Fig. \ref{fig:staf0:stfw0:00} and one discrete state from In Fig. \ref{fig:staf0:stfw0:01}. The initial state $A_{D}B_{IDLE}$ corresponds to the initial state from In Fig. \ref{fig:staf0:stfw0:00} paired with the initial state from Fig. \ref{fig:staf0:stfw0:01}. The noteworthy features of Fig. \ref{fig:staf0:stfw0:02} are: \begin{itemize} \item It is the result of a mathematical algorithm applied to Figs. \ref{fig:staf0:stfw0:00} and \ref{fig:staf0:stfw0:01}. If the underlying system consisted of more than two automata, the algorithm could be applied repeatedly to generate a single automaton with a single large discrete state space. \item The upper bound on the number of discrete states in the shuffle of two automata is the product of the number of discrete states in each. Note, however, that $A_{D}B_{UP}$ and $A_{U}B_{DOWN}$ don't ``truly'' exist. The reason is that the synchronization mechanisms between the two automata ensure that these states are instantly exited as soon as they are entered. Thus, a system of equivalent functionality can be constructed with six discrete states rather than eight. \end{itemize} Although the preceding example is contrived, it illustrates the flavor of the framework and how separate automata with synchronization mechanisms can be combined (and perhaps also ``separated'' or ``factored'', \S{}\ref{srin0:star0}). It should also be apparent that tools can verify a great deal about the system through symbolic manipulation. Properties that can be verified include: \begin{itemize} \item \emph{Reachability:} it can be symbolically determined whether or not each state is reachable (the algorithms involve determining symbolically which values timers can achieve in each discrete state and comparing that information against transition functions---some transitions cannot ever be taken). \item \emph{Liveness:} it can be symbolically determined whether the system can enter a state where no inputs to the system can cause all of a set of states to be reachable. \end{itemize} The example comes \emph{very} close to the way practical software systems are constructed. Generally, state machines in software have transition functions that involve time and the states of other state machines. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Human Tendencies} \label{staf0:shtd0} My experience in industry is that human beings do badly with the design of stateful controllers. Typical tendencies: \begin{itemize} \item \textbf{Bloating of the controller state space:} \;It is very common for engineers to design a controller with a discrete state space that is too large. The prototypical example is an engineer who finds a way to implement a purely combinational function using sequential logic. In the most humorous case (purely combinational logic implemented as sequential logic), the system usually behaves correctly. Serious software defects most typically come about through \emph{subtle} design mistakes. A typical software defect involves two or more software components with some interaction that enter states such that the software can't recover. \item \textbf{Inability to comprehend all possible behaviors of the system:} Very stateful systems tend to be incompatible with human cognitive ability. Even when the problem is well-defined and when the controller and plant are operating perfectly, human beings don't do well at considering every possible behavior. \item \textbf{Inability to comprehend how the system may behave in the presence of failures:} Very stateful systems are often designed to be tolerant of certain types of sensor and actuator failures (usually in the sense that the failures will be detected and the system will employ a different algorithm to operate without a specific sensor or actuator)\@. Such fault detection and tolerance normally complicates the software design substantially. However, even without designed-in fault tolerance, there is the need to design controllers to tolerate the faults that can occur in any practical system. Specific scenarios that must be tolerated: \begin{itemize} \item Spurious reset of the controller (which will normally reset the controller to its initial state but leave the plant undisturbed). (This directly implies that the system must recover from the initial state of the controller combined with any state of the plant.) \item State upset of the controller (due to electrical noise, internal software errors, etc.). (This directly implies that the system must recover from any state of the controller combined with any state of the plant.) \end{itemize} Except in simple cases, human beings don't have the cognitive capacity to consider all possible behaviors when both the controller and the plant may start in any state. \end{itemize} One example that comes to mind from product development is an automobile transfer case controller where it was discovered that if the electrical connector was removed, the transfer case mechanical components repositioned, and the electrical connection restored; the controller would not recover into normal operation. Human beings are not good at mentally exploring all possibilities, and even a disciplined manual process can't be used because the combinations sometimes number in the thousands or more. A mathematical framework and tool support are required. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Code Generation} \label{staf0:scgn0} In most engineering environments, software is generated from software designs that involve timed automata. (Some of the techniques used to create compact code are described in \S{}\ref{sfrr0}.) For some types of systems, there has been success in using existing tools to generate code directly from the software design (using tool chains from \emph{The Math Works} or \emph{I-Logix}). It is, however, known from experience that a clever human programmer can generate more compact code than any existing tool; so code generation tools have not penetrated cost-sensitive automotive products involving 32K of FLASH or less. There are two primary arguments against manual generation of code: \begin{itemize} \item Code is redundant with respect to a software design. In general, it does not make economic sense to maintain redundant information using human labor. \item The act of optimizing implementations typically destroys the clear relationship between design and code. Furthermore, changes to the design---sometimes even small ones---can invalidate the mathematical basis for certain optimizations. Optimized code becomes unmaintainable. It would be more economical to evaluate the viability of optimizations and to generate code using software tools (rather than human labor). \end{itemize} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Formal Verification of Properties} \label{staf0:svpr0} Typical design tools provide simulation capability, and there is a large body of theory and best practice about how to design test cases based on a stateful design. Still, the following problems remain: \begin{itemize} \item Systems with a large discrete state space elude human understanding. \item It is very laborious to test systems with a large discrete state space. \item It isn't possible to fully test systems with a large discrete state space. \item It is possible (and common) to make a good faith effort at comprehensively testing systems but still to overlook unacceptable behavior. \end{itemize} \emph{Simulation and testing are not enough.} For complex safety-critical systems, simulation and testing do not provide enough assurance about the behavior of the system. Formal verification of properties would involve making mathematical assertions about how the system must and must not behave, and then allowing tools to verify the properties. Possible types of properties: \begin{itemize} \item \emph{Required behavior:} For example: \emph{When the brake pedal switch is closed, the brake lights must always come on within 200ms.} \item \emph{Required absence of behavior:} For example: \emph{The airbags can never deploy without at least one body deformation sensor indicating body deformation.} \item \emph{Liveness:} For example: \emph{A certain set of states is always reachable by manipulating certain inputs.} \end{itemize} The only tool I'm aware of that allows formal verification of properties is UPPAAL. However, the modeling framework of UPPAAL isn't rich enough to support practical embedded systems.\footnote{The tool chains from \emph{The Math Works} and \emph{I-Logix} don't attempt formal verification at all.} I would tend to view formal verification of properties as a last line of defense against egregious software defects (i.e. as a practice that cannot stand alone)\@. Formal verification should be combined with all other known best practices. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{FLASH/ROM Reduction Techniques} \label{sfrr0} In this section, I mention some of the FLASH/ROM reduction techniques used by human programmers. Important points: \begin{itemize} \item All of the techniques have a mathematical basis. \item The techniques are complex to apply and best carried out by tools. \item The mathematical basis of the techniques is non-trivial. There are many unexplored corners. \item The techniques distort the correspondence (i.e. the resemblance) between design and code, and make code unmaintainable (it would be better only to generate code from designs and never to maintain code directly). \end{itemize} The list of techniques presented is not exhaustive (far more techniques exist). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{General Paradigm of Software Construction for Small Microcontrollers} \label{sfrr0:sgsc0} This discussion is confined entirely to systems where a stateful design is implemented directly as code (with no tabulation or compression of the design). Other paradigms are possible. For example, at least one tool on the market implements stateful designs as state transition tables that are evaluated at runtime by a table interpreter. My experience with these types of systems is that there is always a real-time performance penalty (but certainly not always a FLASH penalty). My research interests do also include event-driven systems and systems where the design is not implemented directly as code; but these systems are not mentioned for brevity. The most common paradigm for small systems is ``\emph{a collection of cooperating timed automatons}''. The most typical abstraction of these systems is a data-flow diagram, with RAM variables (i.e. global variables) used as the interfaces. There is a body of theory and best practice about what separates good software designs and implementations from bad (Parnas and the classic coupling and cohesion spectrums come to mind). However, in small systems, it simply isn't possible to implement the systems using classic ``good'' programming practice---formal parameters, pointer dereferencing, and access to variables in stack frames all bloat FLASH size under the weak instruction sets typical of small microcontrollers. It is helpful to take a step back and consider the possibility that global variables (the second-strongest form of coupling in the classic coupling spectrum) aren't inherently harmful; but rather that it is the way in which global variables are typically used that causes harm. The harmful aspects of global variables seem to be: \begin{itemize} \item If global variables are tested \emph{and assigned} in more than place, the variable actually becomes an automaton and adds to the state space of the system. \item Global variables lead to unrestrained connectivity: \emph{any} software component can access the variables. Additionally, state is not ``shed'' as functions return (as happens with formal parameters and local variables)\@. This leads to connectivity that often skips levels of the calling tree (making it very difficult to understand the software). \end{itemize} Small systems often have design rules to mitigate the harmful aspects of global variables. The design rules tend to involve these restrictions: \begin{itemize} \item A global variable used as an interface can be assigned by only one software component (a 1-writer, $n$-reader restriction). \item A global variable used as an interface has its readers/writers represented in design documentation (so that the connectivity created by the global variable isn't accidental or unrestrained). \end{itemize} The design rules typically also include provisions for global variables used as interfaces that are tested and assigned by more than one software component (i.e. interface automatons). The simplest example of such an interface is a semaphore that is set \emph{T} by one software component and tested and set \emph{F} by another software component, but the design rules are far more general. Note that tools can be used to allow a system to be phrased in a way consistent with the traditional coupling spectrum but implemented efficiently for small microcontrollers. For example, some compilers are able to analyze the calling tree and place variables of storage class \emph{automatic} into statically overlaid\footnote{Statically overlaid based on the calling tree: one function's automatic variables can be overlaid with another only if an analysis of the calling tree determines that the two functions cannot be active at the same time.} areas of memory rather than in a stack frame. Similar tool support could be developed for the notion of \emph{automatic} bitfields and to restrain the connectivity introduced by global variables to be consistent with the product design. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Near versus Far (Addressing Modes)} \label{sfrr0:snvf0} Most small microcontrollers (TMS370C8, 68HC05, etc.) have two non-indexed addressing modes, typically called \emph{direct} and \emph{extended}. Instructions using the direct addressing mode typically have the address encoded as a single byte, and can address only locations \$00 through \$FF\@. Instructions using the extended addressing mode typically have the address encoded as two bytes, and can address locations \$0000 through \$FFFF. For lack of better nomenclature, I'll call the RAM locations that can be addressed using short instructions \emph{near} RAM, and the RAM locations that require long instructions \emph{far} RAM. When fixed RAM locations are used as interfaces (\S{}\ref{sfrr0:sgsc0}), one can save substantial FLASH by allocating the variables that are referenced most often throughout the software into near RAM. In automotive software, variables such as gearshift position and vehicle speed are typically referenced many times throughout FLASH. Most programmers would automatically place these into near RAM. However, for most variables, it isn't obvious whether these should be placed into near or far RAM. Software developers often write small utility programs to scan all software modules to determine the number of references to each variable. This information is then used to allocate the variables with the most references into near RAM. The FLASH savings from using this technique is typically large. As an example, assume there are ten variables each referenced 50 times throughout the software. The savings of placing these variables into near RAM versus far RAM is typically about $50 \times 10 = 500$ bytes of FLASH (more than 1\% of a 32K FLASH). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Treatment of Time} \label{sfrr0:stot0} The way that time is measured is usually the single most important decision in a small embedded system. Typically, many software components have to measure time intervals, so a suboptimal decision about the mechanisms greatly increases FLASH consumption. The best mechanism known is to arrange all software timers into binary decades and to decrement the timers en masse (Fig. \ref{fig:sfrr0:stot0:00}). \begin{figure} \begin{small} \begin{verbatim} unsigned char modulo_counter; unsigned char timers_modulo_1[MOD1_COUNT]; unsigned char timers_modulo_2[MOD2_COUNT]; unsigned char timers_modulo_4[MOD4_COUNT]; void decrement_timers(void) { int i; modulo_counter++; for (i=0; i