Software engineering, program management
The problem Software is expensive to design! – Industry estimates put software development labor costs at 1.5 hours per machine instruction – Software developers are expensive labor – Most "real" programs contain thousands, if not millions of lines of code The quality of much software and most documentation is poor
The problem Even after extensive testing, software frequently has bugs – Testing can prove the presence of bugs, but testing can (almost) never prove the absence of bugs! – Testing and debugging software can take as much or more time than the original planning and writing Most new software is completed later than forecast (2x or 3x longer is common) Programming can be tedious, boring work
The problem The design process – Software development, as any engineering effort, should be based around a logical design methodology whether for a lab assignment or as part of a large SW design team
The problem Need Concept Decomposition Specification Design Test / Validation Production Deployment Maintenance Disposa
Programmer's "goals" what's important? Write the shortest program – Uses less memory, so hardware requirements are less – Often trading expensive human effort for inexpensive hardware costs – Encourages programming "tricks"
Programmer's "goals" what's important? Write the fastest program – Get the program's execution done as quickly as possible – Not always an important goal in embedded systems – More payoff from developing and implementing an efficient algorithm – Use profiling as a guide to optimizing the already good algorithm
Programmer's "goals" what's important? Write an easily understood program – The programmer and others must be able to understand the function of the instructions in the program – Complex programs are hard to modify and maintain – Good documentation – KISS principle
Programmer's "goals" what's important? Write an easily modified program – Be able to change it to cope with changing environments – Requires planning and effort during the design phase – Effort is extremely cost effective compared to redesign effort – Focus on long-term success
Programmer's "goals" what's important? Meet the schedule – Avoid the vaporware syndrome – Organize and plan for changes – Failure can mean loss of market share
Program design The design process lends itself to an iterative problem decomposition in a divide-and-conquer approach Decompose overall task into smaller subtasks that can be written and tested independently
Program design
Avoid spaghetti code and designs – Each module should have single entry / exit points
Program design Structured programming uses 3 basic control structures
Documentation Good documentation is mandatory for good code This provides information needed by humans to understand the operation of the program and enable efficient maintenance and modification For a given code segment / block / function, well thought out, detailed comments in the “header” can help reduce the need for line-by-line comments within the code itself
Documentation Programs can be over or under documented Examples: – Wrong: LDAA #$56 ; load ACCA with $56 – Right: LDAA #$56 ; initialization word for ; DDRC -- bits 1,2,4,6 ; are outputs
Documentation Each code segment / block / function should include comments that … – Identify the routine’s name and function – Who wrote it and when – Describe the algorithm being implemented – Explain the parameters being passed to and from the routine – List other routines that call this routine or are called by this routine CONTD
Documentation – Describe register and memory requirements -- which locations are altered? – Give the modification history – Do not overwhelm the reader (particularly in-line comments) Software written for the labs and design projects is expected to follow these guidelines! – For a good example, see the code included with the sample lab report on the WI web page
Documentation Main routine should be mostly calls to subroutines – If something takes more than a few instructions, don’t put it directly in the main routine – make it a subroutine – Main routine will usually be an infinite loop – Example: ;******************************** ; Thermometer: This program reads an ; analog value from a temperature sensor ; every 0.5 seconds, and displays the ; temperature on an LCD display. ;********************************
Documentation ORG $B600 Thermometer: lds #$1FF ; initialize stack pointer jsr InitSystem ;initialize the system Loop: jsr GetAnalogValue ; get A/D value from ; temp sensor jsr ConvertTemp ; determine the ; temperature jsr DisplayTemp ; display it on LCD jsr Delay0P5 ; delay for 0.5 seconds bra Loop ; repeat
Documentation Include a header with each subroutine: ;******************************** ; Convert_Temp: This routine converts ; an analog value (assumed to be an 8-bit ; binary fraction between 0 and 1) to a ; Fahrenheit temperature using the formula ; temp = (value * 180) + 32 ; Input: ACCA = 8-bit analog value ; Output : ACCA = temperature ; Registers modified: CCR ;********************************
Documentation Convert_Temp: pshb ; save ACCB ldab #180 ; calculate temp mul ; = (value * 180) + 32 adca #32 ; ACCA = temp pulb ; restore ACCB rts ; return
Summary Programs should be well-designed and well- documented Use a modular design – Each subroutine should perform a single function – Subroutine interfaces should be clearly defined Focus on making programs easy to understand and easy to maintain – Bonus: They’re often easier to debug CONTD
Summary – Avoid programming “tricks” unless they are truly needed for performance or memory requirements – If you need to use “tricks” -- document them! Time spent on design (before coding) is usually a good investment