ENEL712 Embedded Systems Design Dr. Jack Xuejun Li Auckland University of Technology Copyright @ Jack Xuejun Li 2022 ENEL712-Embedded Systems Design Table of Contents L1 L2 L3 L4 L5 L6 L7 L8 L9 L10 L11 L12 L13 L14 L15 L16 L17 L18 L19 L20 L21 L22 L23 L24 2 ENEL712-Embedded Systems Design 3 ENEL712-Embedded Systems Design Lecture 1 Introduction to Embedded Systems Microcontrollers Revision 4 ENEL712-Embedded Systems Design Personal View • Embedded/microcontroller courses are the most fun papers at AUT. • Why? – A real application of theory • Mathematics, control, signal processing, software engineering, and programming can all form part of an embedded system – Take “control” of the world(s) around you • Measure – Use your knowledge of electronics and sensors to measure the environment • Compute – Use signal processing and mathematics to decide the best course of action • Actuate – The fun part, make something you do what you want it to! – Motors, lights, actuators, anything that can be influenced electronically/mechanically! – And… Who doesn’t like robots! Robots are tangible, moving, interactive examples of embedded systems 5 ENEL712-Embedded Systems Design Microcontrollers Revision • To get everyone on the same page as much as possible we will spend the rest of this lecture with some microcontroller basics • Next lecture you will decide the lecture content – revision wise that is! 6 ENEL712-Embedded Systems Design • Back to Basics [1] What is an Integrated Circuit (IC)? – Aka a “chip” – but we won’t call it that! – An IC is a collection of electronic circuits constructed out of silicon, often fabricated at the µm or nm scale. This allows billions of semiconducting components (such as transistors) to be placed in a very small area, thus greatly increasing the functionality achievable by small and lightweight devices. • What is a microcontroller? – In essence it is a small computer, containing one or more processors, memory, and programmable input/output peripherals such as timers and communication interfaces. They often contain both Flash (non-volatile program memory) and RAM (data memory), and importantly, contain virtually all peripherals internally, thus reducing off-chip component cost and size. Microcontrollers are used in embedded applications where size, weight, cost, power, or a combination of all may be constrained, thus excluding the use of a PC or microprocessor. • What can you do with a microcontroller? – Lots and lots and lots of things! Just about every modern electronic device has a microcontroller/microprocessor in it, from your TV remote to your TV, your washing machine, your phone, and even your USB flash drive. Microcontrollers can be programmed to perform a multitude of tasks. 7 ENEL712-Embedded Systems Design Back to Basics [2] • What do you need to use a microcontroller? – DC Power Supply (typically 3.3V-5V), programmer (ISP or JTAG), external oscillator (crystal or resonator), PCB or breadboard (depending on the package), system to interface/control/measure. • Who are some major microcontroller manufacturers? – ATMEL, Microchip, STMicroelectronics, NXP Semiconductors, Freescale, Texas Instruments • Why would you not use a microcontroller? – When a simple analogue/digital circuit would suffice (e.g. a 555 timer, OpAmp or 7400 logic) or if the computing performance required means a microprocessor, FPGA or PC would be required. 8 ENEL712-Embedded Systems Design Back to Basics [3] • What does “8 bit microcontroller” mean and are there other versions? – Common formats are 8, 16 and 32bits, where the number of bits refers to the “width” in bits of the internal data buses and internal registers. The size of the registers affect the arithmetic and logic operations that can be performed, as well as the I/O port sizes. Typically, more bits = higher performance and more memory available. • Where can you buy microcontrollers and are they expensive? – Microcontrollers are cheap! They can be picked up from as little as a dollar, with most $5-$10. You can buy them from Jaycar, or online from Element 14, RS Components, Digikey and other retailers. • Are microcontrollers used in the control or power industries? – Absolutely! PLCs, smart meters, intelligent transformer tap changers, line condition monitoring, motor starters, smart sensors, robotics, the list goes on! – The “smart grid” is also going to be predominately embedded based, and is the new push for the power industry! 9 ENEL712-Embedded Systems Design Back to Basics [4] • Can microcontrollers “talk” to each other, or other electronic devices? – They can talk electronically! Serial (e.g. RS232), SPI, I2C, USB, Ethernet, CAN, RS485… the list goes on. And don’t forget parallel, and any other custom/manufacturer specific interface via bit-banging (software implementation of a hardware protocol). • Can someone who knows only about PC software (e.g. a computer science graduate), program a microcontroller? – They can write the core functionality, perhaps the control algorithm or data structures used, but with respect to the hardware and register-level coding, it is unlikely. Therefore as electronic engineers, you are in a unique position, understanding both the software and the hardware. • What is Arduino, and why is it so popular? – Arduino is an open-source hardware and software solution for beginners to start programming microcontrollers that interact with their environment. It uses a simplified C/C++ language with an easy to use interface to hardware peripherals, removing the need for users to deal with registers. Because of this, many more non-technical/specialist users can start programming faster and get impressive results. BUT, as you are all technical people, we will not skip this “hard stuff”! 10 ENEL712-Embedded Systems Design Our Microcontroller • ATMEL AT90USB 8bit microcontroller TQFP Complicated! Lots of internal components! OR QFN 11 ENEL712-Embedded Systems Design LOTS of Functionality! 12 ENEL712-Embedded Systems Design What We Expect You to Know • How to: – Write a “hello world” type program for a microcontroller (e.g. flash an LED) – Use common peripherals on an ATMEL micro such as: • • • • • ADC USART Timers Interrupts GIO – Be able to write a program that uses multiple peripherals to complete a simple specification • This means your knowledge of C should be reasonable – Functions, control statements, loops, bit masking, header files, etc – Time to revise if not! • However it is fine if you found all the above hard, this course will hopefully help and make it fun! 13 ENEL712-Embedded Systems Design Lecture 2 Microcontroller Operation & Architecture 14 ENEL712-Embedded Systems Design What is a Microcontroller? • In simplest terms a microcontroller is: – 1) A simple computer processor – 2) Depending on the manufacturer, memory, A/D convertor, timers, I/O, etc, are added – 3) This is all placed in a standard IC package (e.g. DIP / TQFP / QFN) – 4) Simple software is developed and loaded to control its functionality • The key is that the virtually all components that you might require (CPU, memory, IO) are packaged internally within the IC – Almost a ‘drop in’ solution for an embedded system DIP TQFP QFN 15 ENEL712-Embedded Systems Design How does a Microcontroller Work? • When the Power is first Switched On – Initially, everything is disabled, while the nominal power supply voltage is reached and the oscillator frequency stabilizes (ms) – Once powered up and stabilized, peripherals are initialized to their default values (i.e. pins as inputs, timers stopped), then Special Function Registers (SFRs) are initialized with the state of all peripherals (μS or nS) – The Program Counter (PC) is set to zero, and the first instruction is fetched from memory into the Central Processor Unit (CPU). – The CPU decodes the instruction and executes it. – The PC is incremented by 1, and the process is repeated, millions or even billions of times per second. 16 ENEL712-Embedded Systems Design Simplified μC Architecture 17 http://www.mikroe.com/chapters/view/64/chapter-1-introduction-to-microcontrollers/ ENEL712-Embedded Systems Design AT90 AVR Architecture In order to maximize performance and parallelism, the AVR uses a Harvard architecture – with separate memories and buses for program and data. Instructions in the program memory are executed with a single level pipelining. While one instruction is being executed, the next instruction is pre-fetched from the program memory. This concept enables instructions to be executed in every clock cycle. 18 ENEL712-Embedded Systems Design Central Processing Unit (CPU) • The CPU controls the operation of the microcontroller, fetching, decoding and executing the instructions from program memory. – Comprised of the highlighted components 19 ENEL712-Embedded Systems Design CPU: Program Counter • The program counter (PC), also known as the instruction pointer (IP), keeps tracking of which instruction is to be fetched next. • It is basically just a binary counter, except it is counting program memory addresses • It is incremented after each instruction is fetched 20 ENEL712-Embedded Systems Design CPU: Instruction Register • The instruction register (IR) is an intermediate register (quick access memory) that holds the instruction that has been fetched from program memory • It is stored in this register while it is been decoded and executed – In some processors the IR and decoder are the same component • Due to pipelining, the IR is included to allow a new instruction to be loaded, while the current one is being decoded and executed. 21 ENEL712-Embedded Systems Design CPU: Instruction Decoder • The instruction decoder (ID) takes the fetched instruction and decodes and executes it • The instruction determines what register information is to be used, what the ALU is to do with it, and where the result is to be stored • In other words, the decoder takes the machine code and turns it into control signals which are sent to other parts of the CPU 22 ENEL712-Embedded Systems Design CPU: Arithmetic Logic Unit (ALU) • The arithmetic logic unit (ALU) carries out operations such as: – – – – – – Integer Addition Integer Subtraction Integer Multiplication Complementing Bit shifting Bit rotation • The operation to be performed and the location of the data to be operated on and provided by the program instructions. • The ALU has direct access to all of the general purpose registers, for loading data and storing results. • The ALU also controls the sequencing of the instructions and keeps track of the events such as interrupts and resets. 23 ENEL712-Embedded Systems Design CPU: General Purpose Registers • A general purpose register is unique memory that the ALU has direct access to. • It is faster than accessing memory from RAM, and thus allows single cycle arithmetic operations (load, execute and store in 1 cycle). • Data is normally loaded from RAM into a GP register, operated on, returned to a GP register, then returned to RAM once the calculation is complete. • The AVR has 32 8bit general purpose registers, with the last 6 dedicated for 16 bit access 24 ENEL712-Embedded Systems Design CPU: Status Register(s) • The Status Register shows the state of the CPU after each instruction has been executed. • The status register bits can control the operating sequence of the program – Such as overflow, a carry, the result is negative, or the solution was zero • One of the SREG bits also controls interrupts for the entire MCU 25 ENEL712-Embedded Systems Design CPU: Fetch -> Decode -> Execute • The basic operation of a CPU is to: – Fetch – The instruction is fetched from program memory to the Instruction Register – Decode – The Instruction Decoder decodes the instruction – Execute – The decoded instruction is executed • This linear process is repeated for every instruction, which for the AVR is up to 1MIPS per MHz, or one million instructions per second, per MHz. – This infers that most instructions are single cycle, a feature of a RISC processor • The AVR architecture allows this by: – Decode and execute are contained within the same operation – Fetch and execute are pipelined, made possible by the Harvard architecture 26 ENEL712-Embedded Systems Design Pipelining • Pipelining allows multiple jobs within a processor to be completed in parallel – The same concept also applies to manufacturing lines • Within the AVR, after the first cycle, both fetch and execute can occur in parallel – This is possible as they are independent tasks, and do not share resources • There is a risk though – if the instruction changes the execution of the program, then the pre-fetched instruction is useless, and the pipeline has to start again 27 ENEL712-Embedded Systems Design AT90USB Architecture Note most of the components within the AT90 we have now identified! CPU, Memory (next lecture), Peripherals, Programming, and Clocking (next lecture). 28 ENEL712-Embedded Systems Design RISC vs CISC • RISC: Reduced Instruction Set Computer [AVR, ARM] – – – – – – Mostly simple, single-cycle instructions Low cycles per second, large code size Harder for an assembler programmer (or compiler) Pipelining possible due to uniform execution time More efficient in some circumstances Low power consumption as less transistors! • CISC: Complex Instruction Set Computer [8051, x86] – – – – Complex, multi-cycle instructions High cycles per second, small code size Easy for an assembler programmer Complex hardware 29 http://cs.stanford.edu/people/eroberts/courses/soco/projects/risc/risccisc/ ENEL712-Embedded Systems Design Lecture References • Embedded Systems 2014 – © Mark Beckerleg & Alan Smith • ATMEL AT90USB1287 Data Sheet • Architecture and Programming of 8051 MCUs – MikroElektronika – http://www.mikroe.com/products/view/267/architecture-and-programming-of-8051mcu-s/ 30 ENEL712-Embedded Systems Design Lecture 3 Microcontroller Memory and Clock 31 ENEL712-Embedded Systems Design AT90 AVR Architecture As detailed in the previous lecture, the AVR series of microcontrollers use the Harvard Architecture, in which the program and data memory are physically separate. In this lecture we will be looking at these two types of memories, as well EEPROM and address and data buses. We will also examine how the internal clocking of the CPU, memory and other peripherals is achieved. 32 ENEL712-Embedded Systems Design Harvard Architecture • The Harvard architecture is a type of computer architecture where there are two separate memory systems, one for the program (the instructions as machine code), and one for data (run-time variables). • This architecture is used by many microcontrollers, including the AVR, as it allows concurrent instruction and data access. It also allows pipelined fetchexecute cycles, further increasing the speed of the CPU. • Advantages include allowing different memory types between program and data (e.g. RAM vs ROM or bit width), different timing, and the concurrent access of both memories. • Disadvantages include the increase in hardware, as well as complexity in initializing values in data memory. 33 https://embeddedbasics.wordpress.com/2009/12/18/von_neumann_architecture_vs_harvard_architecture/ ENEL712-Embedded Systems Design Von Neumann Architecture • Von Neumann architecture is the other main computer architecture. It has only one memory system where both the program and data reside. • Historically allowed for programs to modify themselves as they ran (self-modifying code). • Often characterised by the “Von Neumann Bottleneck”, where the CPU is waiting for memory to become available before it can fetch and execute the next instruction. • Modern high-performance CPUs incorporate aspects of both Harvard and Von Neumann architecture, especially via caches. 34 ENEL712-Embedded Systems Design AVR Memory Program Memory (Flash) General Purpose Registers Register Memory (SRAM) Data Memory (SRAM) External Data Memory (Optional) (SRAM) EEPROM 35 ENEL712-Embedded Systems Design AVR Program Memory: Flash (“ROM”) • The AT90USB128 contains 128Kbytes of “Onchip In-System Reprogrammable Flash Memory” for program storage • This memory is organised as 64K x 16 (64K 16bit words) – This is because most AVR instructions are 16 or 32 bits wide • The Flash memory has an endurance of at least 100,000 write/erase cycles – This means you can’t write more than 100,000 new programs to the memory without risk of damage • Flash is technically a type of EEPROM, however it functions similar to both ROM and RAM. – For our purposes, it is only possible to write to Flash using a programmer/JTAG*. – Therefore we regard the program memory as nonvolatile Read Only Memory (ROM) 36 ENEL712-Embedded Systems Design The Bootloader • Generally, AVR microcontrollers do not come with a bootloader, and instead the application is started directly from the first address in program memory – However the AT90USB actually comes with a USB bootloader installed • However you can write your own bootloader, which allows your microcontroller to selfprogram itself – For example updating the firmware on a device • This contradicts the last slide – it is possible for the CPU to program its own flash memory – However it is very complicated and not something we will cover in your degree! – Normally this is done using USB or a UART to update the Flash memory from a PC program http://electronics.stackexchange.com/questions/27486/what-is-a-boot-loader-and-how-would-i-develop-one 37 http://blog.schicks.net/wp-content/uploads/2009/09/bootloader_faq.pdf ENEL712-Embedded Systems Design AVR Data Memory: SRAM (RAM) • The AT90USB128 contains 8Kbytes of internal Static Random-Access Memory (SRAM) for data storage • The memory is organised as 8K x 8 (8K 8bit words) – Hence 8 bit microcontroller – Note different size from program memory (Harvard Architecture) • Static RAM is volatile – it is erased when the power is removed – However it does not need to be ‘refreshed’ like DRAM • As well as internal SRAM, the AT90 can also use external SRAM if connected to the µC – External RAM is slower to access, and must be carefully laid out on the PCB • In addition, the first 0xFF memory locations in RAM contain the registers for the microcontroller 38 ENEL712-Embedded Systems Design EEPROM • EEPROM – Electrical Erasable Programmable Read-Only Memory is a type of non-volatile memory • The AT90USB128 contains 4Kbytes of EEPROM memory suitable for storing data collected during run-time – I.e. not constants declared when you program the microcontroller – E.g. user settings for an embedded device • EEPROM memory is nice to use as you can read and write individual bytes, rather than ‘pages’ as in Flash. (External EEPROM) • It is slow however, and like Flash, has a finite endurance, typically 100,000 write/erase cycles 39 ENEL712-Embedded Systems Design The Bus System • All parts of the CPU and memory, as well as the peripherals, must be able to communicate with each other • The AVR architecture allows this a number of buses: – Address Bus • – Carries data between ALU, memory, and peripherals Control Bus • • Carries the address in memory where instructions or data can be found Data Bus • – Note Data Bus Width! Controls the flow data using read, write and enable lines Activity on the buses is controlled by the ALU and the program 40 ENEL712-Embedded Systems Design Data Memory Usage SRAM Init Vars Unint Vars 0x0100 C Heap Dynamic Memory Grows Up --> Stack Pointer Free RAM 0x10FF Stack <-- Stack Grows Down • When using a C compiler, the RAM available is divided up between global variables (both initialized and uninitialized), the C Heap (dynamically allocated memory, e.g. malloc), and the Stack (local variables, temporary data) • As we have a fixed amount of memory, it is possible that the Heap and Stack can crash into each other (major bug) • However normally on a microcontroller we avoid the use of dynamically allocated memory – • It leads to non-deterministic run-time behaviour and the memory problems above Therefore, RAM is normally only limited by the global and local variables 41 ENEL712-Embedded Systems Design Stack & Stack Pointer SRAM Init Vars Unint Vars 0x0100 C Heap Stack Pointer Free RAM 0x10FF Stack • The Stack is mainly used for storing temporary data, for storing local variables and for storing return addresses after interrupts and subroutine calls • The Stack is accessed sequentially, rather than randomly, and behaves as a Last-In-FirstOut (LIFO) buffer/queue • To keep track of the next free memory location in the stack, the Stack Pointer is a 16bit register that contains the address of the next free location – – When a byte is stored (pushed) onto the stack, the Stack Pointer is decremented When a byte is read (popped) from the stack, the Stack Pointer is incremented • When a subroutine or interrupt is called, the program counter value is stored on the stack, so once the subroutine has completed, the program can continue from where it left off • The most important aspect of the Stack is it is completely automatic. The push and pop functionality is implemented as instructions within the microcontroller, and the stack pointer is updated automatically by hardware 42 ENEL712-Embedded Systems Design System Clock Architecture USB Only Note different freqs. Watchdog Only (Not very useful) 43 ENEL712-Embedded Systems Design Microcontroller Clock Sources • The AT90USB128 has 4 options for supplying the system clock – – – – • Low power crystal oscillator (external) [default] Low frequency crystal oscillator (external, nominally 32.768kHz) Calibrated internal RC oscillator (internal) External clock (external) The system clock preference is set up by programming the corresponding fuse bits – By default, the device comes setup expecting an external crystal oscillator and the clock prescaler set as 8 – i.e. an 8MHz crystal will result in f_cpu = 1MHz. 44 ENEL712-Embedded Systems Design Low Power Crystal Oscillator • When using the low power crystal oscillator option, normally we will be using either an 8 or 16MHz crystal – Note 16Mhz requires a higher Vcc! • To tell the microcontroller what the frequency of the crystal is, you program the corresponding fuse bits • You also need to tell the microcontroller the start-up time expected before the crystal frequency stabilizes – Longer is more conservative! 45 ENEL712-Embedded Systems Design Calibrated Internal RC Oscillator • The other option, used normally just during initial development, is the internal RC oscillator – Convenient as it doesn’t require any external components • Unfortunately its accuracy is poor (8MHz ±10%), thus it is not suitable for many applications – Accurate timing, PWM, and communications interfaces all require an accurate clock source (External Shown) Versus • My advice: for flashing an LED, an internal RC oscillator is OK. For anything more advanced, you will need a crystal. 46 ENEL712-Embedded Systems Design Lecture References • Embedded Systems 2014 – © Mark Beckerleg & Alan Smith • ATMEL AT90USB1287 Data Sheet • Embedded Basics – https://embeddedbasics.wordpress.com/2009/12/18/von_neumann_architecture_vs_harvard_architecture/ 47 ENEL712-Embedded Systems Design Lecture 4 Advanced MCUs and Microprocessors (MPUs) 48 ENEL712-Embedded Systems Design When 8-bits is not enough… • It won’t be long before you are working on an embedded project where you need performance • This could be raw calculation performance (i.e. multiplication / trigonometric functions), it could be increased timing accuracy or it may be the ability to handle more complicated communications interfaces • Regardless of the need, you will hit the upper limit of 8bit MCU performance at some point – Therefore, what are the options available? 49 ENEL712-Embedded Systems Design Atmel XMEGA MCUs • A hybrid 8/16bit MCU is the Atmel XMEGA series – 8bit data bus but 16bit ALU • Wider ALU = better calculation performance with integers > 255 • However the 8/16bit change is only part of the solution – XMEGA MCUs allow you to use the hardware to do more tasks, rather than software • An Event System for automatically triggering peripherals • DMA for automatically saving ADC or Comms data • More hardware peripherals such as AES encryption and LCD screen support 50 http://www.atmel.com/products/microcontrollers/avr/avr_xmega.aspx ENEL712-Embedded Systems Design Hybrid DSP/MCU • Texas Instruments (TI) has a range of 32bit MCUs that combine a Digital Signal Processor (DSP) with an MCU – “DSP performance, MCU ease” – Allow high-speed calculations within a real-time application • “With a 32-bit architecture, DSP processing and advanced control peripherals, the C2000 MCU family enables uncompromising performance for a variety of real-time control applications such as motor control, digital power supplies, solar and renewable energy, LED lighting, smart grid, radar and more.” • “At the core, C2000 MCUs are based around the TMS320C28x 32-bit DSP core, featuring singlecycle 32×32-bit hardware multiplies and singlecycle atomic instruction execution.” [Note a lot of power applications!] 51 http://www.ti.com/lit/sg/sprb176w/sprb176w.pdf ENEL712-Embedded Systems Design ARM • We have all heard the term “ARM” or “ARM processor” • But what is an ARM processor, and what makes it an ARM? Hint! 52 ENEL712-Embedded Systems Design So Who is ARM? • 1985: Acorn RISC Machines • A computer manufacturer who identified a gap in the market for a more powerful processor to bring computer to the masses • Decided to develop their own processor architecture, focusing on RISC (as opposed to Intel with CISC) – RISC = less transistors = less heat and power usage • Early designs were more powerful and less power hungry that competing processors – This trend continued, with transistors counts still much lower than competing processors • Today: ARM Holdings – The result: • ARM reports that in 2010 95% of smartphones used an ARM processor • By 2013 60% of mobile devices in the world use an ARM processor 53 http://reds.heig-vd.ch/share/cours/reco/documents/thehistoryofthearmarchitecture.pdf ENEL712-Embedded Systems Design Why is ARM so Successful? • Business Wise: – ARM doesn’t make IC’s! It licenses the instruction set and architecture for ARM-based products to manufacturers such as Samsung, Atmel, TI, etc • Other manufacturers combine the ARM core with their own peripherals, memory, etc, and sells it as an MCU/MPU. – This avoids the need for constantly changing fabrication facilities, as well as a physical supply network • Technology Wise: – Up until the advent of PDAs (and later Smartphones), battery life for mobile computing was not that interesting • Power saving for desktop processors is not a go/no-go sell • ARM was just another player in the processor market – However once mobile electronics exploded (as well all know), battery life became a huge problem • ARM’s RISC based processors were amongst the most impressive with respect to computing power vs battery consumption • ARM processors allowed manufacturers to provide rich UIs with video and compute-intensive applications, while minimizing the battery drain 54 ENEL712-Embedded Systems Design ARM in Industry • So where do we find ARM processors? Some of the following Processors: - TI OMAP & Stellaris Processors - Qualcomm Snapdragon Processors - Atmel SAM Processors - Samsung Exynos Processors - STMicroelectronics STM32 Processors - Nvidia Tegra 4 Some of the following Devices: - Apple iPhone, iPad and iPod Touch Samsung Galaxy Nokia E90, N93 Sony Xperia X10 Google Nexus S, Nexus 10 Blackberry Playbook HTC Sensation, EVO 3D Nintendo DS & 3DS Canon EOS 5D Seagate FreeAgent GoFlex (HDD) Gumstix Beagleboard Raspberry Pi Pebble (Smartwatch) http://en.wikipedia.org/wiki/List_of_applications_of_ARM_cores 55 ENEL712-Embedded Systems Design Atmel ARM-Based MCUs Typically as you head up the arrow you gain increased performance (DMIPS, a measure of integer calculation performance), increased memory (Flash and RAM) and of course, a higher price & complexity http://www.atmel.com/products/microcontrollers/arm/default.aspx 56 ENEL712-Embedded Systems Design Selecting an Atmel ARM MCU • No matter which manufacturer you go with, you will have a range of ARM based processors to choose from • Atmel has over 200 ARM MCUs and MPUs – Often overwhelming initially – probably 25% of these will fulfil a general specification! – Use the “Product Search” to narrow down specifications of interest • Buy an Evaluation Kit! These are the best way to get started with a new MCU http://www.atmel.com/products/microcontrollers/arm/default.aspx?tab=parameters 57 ENEL712-Embedded Systems Design Implications of using an ARM MCU • PCB Design • – Lots more memory available, both RAM and Flash – About the same • Price – Comparative [!] • • • • Ease of Use – Still a bit more complicated Performance – Greatly exceeds that of traditional 8, 16 and 32bit processors Peripherals – Often more standard peripherals, and more advanced peripherals C Compilers – Lots available, Atmel Studio for ARM is free Memory • Future Outlook – Don’t look to become obsolete any time soon! http://www.techonline.com/electrical-engineers/education-training/tech-papers/4129220/Moving-from-8-and-16-bit-Microcontrollers-to-ARM-Processors 58 ENEL712-Embedded Systems Design Hybrid MCU + ARM • Want an ARM and MCU in a single IC? • F28M3X MCU series from TI provide a single IC with two cores – One ARM Cortex-M3 [OS + Communications] – One C2000 [Real-Time Control] – Don’t let an OS interfere with high-speed loops! • Lots of other hybrid combinations exist! 59 http://www.ti.com/lit/sg/sprb176w/sprb176w.pdf ENEL712-Embedded Systems Design Advanced MCUs: My Advice • Think carefully about your application and what the performance requirements are likely to be – If you don’t know, run some tests with development code and a couple evaluation kits and time it [or better yet, profile it] • Look at the functionality available via MCUs you are already familiar with – Don’t start learning a new MCU if you don’t need to • Ultimately, the simplest (and best) solution is the one that is easiest to develop, easiest to test, and easiest to maintain – If you can’t fit your program in memory, try optimizing your code. But if it just won’t fit, buy a bigger MCU, don’t fight with compiler optimizations or assembly code. • Note a better compiler can also help! – If you can get the performance you require from a simple MCU, use an advanced one. – Remember you may be constrained by cost in industry, so the above doesn’t always work… • But whatever MCU you choose, remember ARMs are currently more complicated to initialize, thus more development time will be required – However the resulting system may be simpler! – Certainly don’t use an ARM because it is ‘cool’ 60 ENEL712-Embedded Systems Design MCU vs Microprocessor Unit (MPU) • In essence, an MCU contains the CPU, memory and I/O needed to function as a standalone device. • An MPU on the other hand, requires external memory, I/O, oscillator, etc, in order to function. • So why would you use an MPU? 61 ENEL712-Embedded Systems Design Advantages of an MPU • Memory: – You are no longer constrained by on-chip memory (or slow external-memory interfaces) • i.e. 2MB Flash is generally the upper limit – MPUs connect to fast external memory (such DRAM and NAND Flash) with GBs available • Computing Power – Want to run an OS such as Linux? You will need 400 DMIPS, a number still challenging for many MCUs • Graphical User Interfaces – Many MPUs come with a TFT-LCD controller, and have the speed and memory available to generate immersive UIs • Connectivity – Want Gigabit Ethernet? To fully utilize its speed, you will need the performance of an MPU – Full speed USB (480Mb/s) is challenging to process on an MCU… 62 ENEL712-Embedded Systems Design Disadvantages of an MPU • Power Supply – MPUs do not often an internal power regulator, thus you will need a robust power supply circuit that can provide a multitude of voltages • Core, Memory, Peripherals, etc • PCB Design Complexity – Much more difficult to design, with many more external components required and often lots of layers (6+) – Tracks to high-speed memory must be impedance matched to achieve high performance • Power Consumption – No free lunches – higher performance = higher power consumption 63 ENEL712-Embedded Systems Design MPUs: My Advice • Low Power, Simple or No UI, or Real-Time OS: – MCU • Graphical UI, Linux / Win10, High-Speed Communications or HighPerformance Applications: – MPU • MPUs are great if you can utilize an OS like Linux which has all the hardware drivers (TCP/IP, USB, Video) built in, making development easier – Many MPU evaluation kits come with Linux and Android ports, meaning you can get up and running really quickly – However, many MCUs also come with software libraries (stacks) to allow you to use more advanced peripherals, but these can be complicated to set up • I personally have never designed bare-metal (no OS) code for an MPU, nor designed hardware for one – This would be a huge undertaking and not one I would quickly start… 64 ENEL712-Embedded Systems Design Lecture References • Embedded Systems 2014 – © Mark Beckerleg & Alan Smith • C2000 Real-Time Microcontrollers – © Texas Instruments – http://www.ti.com/lit/sg/sprb176w/sprb176w.pdf • The History of the ARM Architecture: From Inception to IPO – IQ Magazine – http://reds.heig-vd.ch/share/cours/reco/documents/thehistoryofthearmarchitecture.pdf • MPU or MCU? – © Atmel – http://www.atmel.com/Images/MCU_vs_MPU_Article.pdf 65 Lecture 5 Embedded Digital Communications A (1 of 2) ENEL712-Embedded Systems Design Embedded Communication • Inevitably, in one of your embedded projects your MCU is going to need to ‘talk’ to another IC or peripheral – This is not just a single 0 or 1, but an actual ‘conversation’ with multiple bytes – E.g. another MCU, a smart peripheral such as sensor, motor driver, an I/O device such as WiFi/ZigBee, or even a PC • There are hundreds of standard communication protocols (a standard/set of rules for communications) for that exist, of which a few (6 or so) are common on most MCUs – This week we are going to examine a selection of the most common ones – Most of this should be revision, but we should be going in to more detail than done previously • Hopefully all this content will be useful in future projects! 67 ENEL712-Embedded Systems Design Parallel vs Serial Parallel Serial Optional! • Communication between MCUs and external components (or other MCUs) generally occurs using either Parallel or Serial communications • • Parallel – a bus (multiple bits transmitted concurrently) Serial – a wire (one bit transmitted sequentially at a time) • There are obvious advantages and disadvantages to each – can you think of them? https://learn.sparkfun.com/tutorials/serial-communication 68 ENEL712-Embedded Systems Design PC Parallel Port • The Parallel Port: – An early external parallel interface found on virtually all 1990s - early 2000s PCs – Also known as DB-25 (25 pin) – 8 parallel data pins – Multiple control lines • Common way to connect early printers to a PC • Now virtually superseded by USB and Ethernet – Why? http://en.wikipedia.org/wiki/Parallel_port 69 ENEL712-Embedded Systems Design IDE (Parallel ATA) • IDE (Integrated Drive Electronics) – Another early parallel PC interface, this time internal – Normally 40 pin cable with 16 parallel data bits IDE SATA • Common way to connect early HDDs, CDROMs and Floppy Drives • Now superseded by SATA (Serial ATA) – Why? – Are all parallel interfaces redundant? 70 http://www.cdrinfo.com/Sections/Reviews/Print.aspx?ArticleId=3840 ENEL712-Embedded Systems Design LCD Parallel Interface Example • Many LCDs still come with a parallel interface – Often 4bit or 8bit – Normally 3 control lines • Data is transferred by using the control lines and obeying minimum ‘set up times’, rather than on clock edges • A good programming exercise when learning MCU timing! 71 http://www.farnell.com/datasheets/653644.pdf ENEL712-Embedded Systems Design Serial Interfaces • Serial communications transmits data sequentially – This normally reduces the maximum data rate – But also reduces the number of I/O required • There are two main families of Serial, differentiated by how the clocking is implemented: Asynchronous - Both the transmitter and the receiver have their own clock (hopefully going at the same rate!) Communication is ‘synchronised’ by framing the data, e.g. via start and stop bits More bits required to send the same data, but less wires required Synchronous A common clock line is shared between transmitter and receiver (normally referred to as Master and Slave) Communications is synchronised by default Data can be transferred without framing, but an extra wire is required 72 ENEL712-Embedded Systems Design Asynchronous: RS-232 • RS-232 is one of the most common serial protocols used by embedded designers – However it is now virtually extinct with respect to PCs, any idea why? • Originally designed in 1962 for use with modems and electronic type writers • Allows serial communication with ‘handshaking’ – control lines such as “Clear To Send” and “Data Set Ready” as well as basic error detection • Very simple to implement with only 3 wires required for “full-duplex” operation – Transmit and Receive at the same time 73 Remember separate clocks! ENEL712-Embedded Systems Design RS-232 Protocol Frame Start: Always 0 Data: Yours! Parity: Stop: Calculated Always 1 Start Bit Parity Bit (Optional) Data Bits (5-9, normally 8) Stop Bits (1 or 2, normally 1) 74 Great Summary: https://learn.sparkfun.com/tutorials/serial-communication ENEL712-Embedded Systems Design TTL RS-232 • Generally we do not have ±15V available in our embedded circuit – Therefore real (as per the standard) RS-232 is not typically implemented between processors and peripherals • Instead, we use TTL RS-232, which is what virtually all MCU UARTs support – This uses 0-3.3V or 0-5V instead, as per the below – Same framing, same connections, but more convenient voltage levels TTL RS-232 True RS-232 75 ENEL712-Embedded Systems Design RS-232: Baud Rate, Parity & Common Formats • As RS-232 is an asynchronous interface, the Tx and Rx must agree (i.e. be configured separately) on a data transmission rate, known as the baud rate (bps) – Note that for a given clock frequency, it may not be possible to divide equally into common baud rates! – Why do we not just go as fast as possible? • Parity is a simple error detection mechanism that works if only one bit is corrupted during transmission – See http://en.wikipedia.org/wiki/Parity_bit – The calculation of the parity bit is handled by the UART, as well as detection of corrupted packets. • • It is up to you to check for parity errors though! Common RS-232 formats combine all this information into a short string: – 9600 8N1 (9600 baud, 8 data bits, no parity, 1 stop bit) – 38400 8E2 (38400 baud, 8 data bits, even parity, 2 stop bits) – Both Tx and Rx must be using the same format! AT90USB Example Baud Rate (bps) fosc = 8.0000 MHz U2X = 0 UBRR Error 2400 207 0.2% 4800 103 0.2% 9600 51 0.2% 14.4k 34 -0.8% 19.2k 25 0.2% 28.8k 38.4k 57.6k 76.8k 115.2k 230.4k 250k 0.5M 1M Max (1) 16 2.1% 12 0.2% 8 -3.5% 6 -7.0% 3 8.5% 1 8.5% 1 0.0% 0 0.0% – – 0.5 Mbps 76 ENEL712-Embedded Systems Design MCUs & RS-232 • Generally UARTs are a rare commodity on an MCU – Therefore only use them to connect to peripherals that have no other common interface • They are however the easiest to use, and I have used them up to 1.25Mbps without problem • If you need to communicate with a PC via TTL RS232, the easiest solution is to use an FTDI FT232R: – – • FTDI FT232R The same IC in a USB-Serial convertor Talk via the serial port on the MCU and receive via a COM port on the PC, but use a USB cable TI MAX232 If you must communicate using real (±12V) RS232, the TI MAX232 is a simple solution – – Converts TTL RS-232 <-> RS-232 Avoid if possible! Very noisy due to charge pump 77 ENEL712-Embedded Systems Design Asynchronous: RS-422 and RS-485 • There are several alternative formats to RS232 which offer many advantages • RS-422 – Same framing as RS-232, but transmitted using differential signalling (discussed next lecture) – Increased range (>1km) and data rate – Multi-drop (one Tx, up to 10 Rx) – Half-Duplex (2-wires) [not an advantage!] • RS-485 – Similar to RS-422, but allows a simple network with multiple devices to be implemented – Multi-point (up to 32 Tx and Rx) – Half-Duplex (2-wires) [not an advantage!] – Common with industrial equipment • With longer lines comes the problem of signal reflections due to mismatches in cable and device impedances – You will learn about this in Fields & Waves – Often terminating R & maybe C required 78 ENEL712-Embedded Systems Design Synchronous: Serial Peripheral Interface (SPI) • One of the main problems with RS-232 is that it is asynchronous, meaning it is easy to Tx/Rx garbage if the format+speed is not set correctly – It is also less efficient due to the synchronisation bits • A solution is to synchronise the Tx and Rx, using a common clock line • SPI is a full-duplex, synchronous solution that requires (normally) 4 lines + ground. – – – – No synchronisation bits required! It can be much faster than RS-232 It is simpler to implement in hardware Support for multiple slaves 79 Good Summary: https://learn.sparkfun.com/tutorials/serial-peripheral-interface-spi ENEL712-Embedded Systems Design SPI Communication Master: - Generates the clock (SCK) - Initiates all data transfers via the MOSI line (note slaves cannot communicate between each other) - Controls which Slave is being communicated with using the Slave Select (SS) or Chip Select (CS) line (normally active low) - To read a byte from a slave, a byte must be sent (Tx and Rx happen at the same time) Slave: - Receives the clock (an input) - Responds to data requests via the MISO line - Only controls the MISO line when SS is low (generally), otherwise it is a high impedance pin - Does not initiate any data transfer without being requested to by the Master 80 ENEL712-Embedded Systems Design SPI Clocking • The clock speed of the SPI interface can run up to f_clk / 2 for the AT90USB – 4MHz for us – However always start slower and work up to faster speeds to ensure it is working! • The only complicated part of setting up an SPI interface is choosing the Clock Phase (CPHA) and Clock Polarity (CPOL) – CPOL - 0 = SCK idle low (normal for a clock) – CPHA - 0 = Sample on the leading edge (also normal) – The Slave device’s datasheet should tell you what is expected, but it can be complicated to interpret – However there are only 4 modes, so try them all if you are having problems • Just know what data you should expect back from the Slave! 81 ENEL712-Embedded Systems Design MCUs & SPI • Generally, setting up and using SPI with an MCU is a stress-free exercise – Once you have CPOL and CPHA correct! – Ensure you have the correct voltage levels too! • Programming it to communicate with a peripheral is generally simple as well – Just follow the peripheral’s datasheet • However if you do run into problems, it can be impossible to diagnose without test equipment – I have used a logic analyzer before for diagnosing SPI problems and it has been invaluable – Several cheap USB logic analyzers are available now online which may be useful in future projects https://www.saleae.com/logic/ 82 ENEL712-Embedded Systems Design Synchronous: Inter-Integrated Circuit (I2C) • We saw in RS-232 that asynchronous communication can lead to a data-rate mismatch – We also saw in SPI how many pins were required • A compromise is I2C – Just two wires! – Multi-master and supports up to 1008 slaves without SS/CS lines – Typically up to 400kHz operation with minimal overhead bits • SCL – Serial Clock – Always generated by the bus master • SDA – Serial Data • Note I2C ports are open collector, thus pull-up resistors are required! Great Summary: https://learn.sparkfun.com/tutorials/i2c Note the two pull-up resistors! 83 ENEL712-Embedded Systems Design Start Condition: SCL High THEN SDA Low • Address Frame 2 IC – Always first in any new communication sequence – 7 bit address (can also be 10) – R/W bit indicates whether master wants to read or write – ACK acknowledge bit indicates whether the Slave received the address Protocol Stop Condition: 0->1 SCL THEN 0->1 SDA • Data Frame – After the address frame has been sent, one or more data frames can be sent or received (depending on the R/W bit) – The master continues generating the clock – Most slaves auto increment their registers, thus subsequent reads/writes obtain new data/locations 84 ENEL712-Embedded Systems Design MCUs & • 2 IC There are a number of advanced features of I2C such as: – 10-bit addresses for more slaves – Repeated start conditions for maintaining control of the bus – Clock stretching to allow the slave device to catch-up to the master • Fortunately most I2C peripherals take care of the details for you, allowing you to focus on the data transmission – but note this is still complex! 85 ENEL712-Embedded Systems Design Other Serial Protocols • CAN (Controller Area Network) – Now also common in many microcontrollers, CAN is a standard developed to allow microcontrollers and peripherals to communicate without a designated host PC. – Originally developed for automotive applications, which can have more than 50 discrete control units located around a vehicle – Multiple devices (Nodes) can communicate on the same CAN bus, thus it is a network protocol – Asynchronous (no clock line), although via arbitration, all devices are synchronised • PS/2 – – – – • Used mostly for older keyboards and mice (USB has taken over) Very similar to I2C (although not directly compatible) Also possible to bit-bang (see Chapter 4 in Embedded Systems 2014) A good exercise in learning to bit bang if you have an old keyboard or mouse lying around + Many others (of which many are proprietary) 86 ENEL712-Embedded Systems Design Lecture References • Microcontroller Systems 2015 – © Mark Beckerleg & Alan Smith • Serial – https://learn.sparkfun.com/tutorials/serial-communication – © Sparkfun • SPI – https://learn.sparkfun.com/tutorials/serial-peripheral-interface-spi – © Sparkfun • I2 C – https://learn.sparkfun.com/tutorials/i2c – © Sparkfun • AT90USB1287 Datasheet – © Atmel 87 Lecture 6 Embedded Digital Communications B (2 of 2) ENEL712-Embedded Systems Design Beyond UARTs and 2 SPI/I C • Generally, a serial port and/or SPI/I2C will be sufficient for most embedded communications • The most common reason the above won’t be is due to requiring a higher data rate, longer transmission distance, or connectivity with existing networks – SPI + TTL RS-232 generally max out at 125kB/s – Both won’t achieve anywhere near this over > 0.5m – Note however for embedded products it is normally the low data-rate which is the issue – we can use wireless (e.g. Bluetooth or ZigBee) for longer range communications • In order to achieve both higher data rates (normally termed bandwidth), together with longer transmission distances, we need to examine the two main communication modes 89 ENEL712-Embedded Systems Design Single-Ended Signalling • The simplest communication method is Single-Ended – A single signal line, and a ground return path – (TTL) RS-232, SPI, I2C, PS/2 – Low cost and simple • Single-Ended interfaces have 3 main problems: – Highly sensitive to noise pick up – Crosstalk (interference between physically close lines) – Generation of EMI • For longer distances (> a few metres), or higher frequency (effectively bit rate) transmission, alternative methods have to be used http://www.planetanalog.com/document.asp?doc_id=527833 90 ENEL712-Embedded Systems Design Differential Signalling • The most common modern communications method is Differential – Two signal lines, with the signal in each the complement (inverse) of each other – Receiver responds to the difference between each signal line – USB, Ethernet over Cat5/6, PCIe, HDMI, SATA, RS-422/485 • Major advantages: – Relative noise immunity – Reduced EMI generation – Higher transmission frequency (cable dependent) 91 ENEL712-Embedded Systems Design Elimination of Noise using Differential Signalling "DiffSignaling" by Linear77 - Own work. Licensed under CC BY 3.0 via Wikimedia Commons - http://commons.wikimedia.org/wiki/File:DiffSignaling.png#/media/File:DiffSignaling.png 92 ENEL712-Embedded Systems Design Shielding & Twisted Pairs • • • As well as using differential signalling, most modern communication channels use advanced cable construction Twisted Pairs (physically twisting the differential pairs together), are used to cancel out EMI from external sources, as well as reduce crosstalk Foil shielding is also used to prevent EMI from external sources being induced into the conductors Note that as the bandwidth (effective frequency and therefore data rate) of the cable increases – so too does the level of shielding! http://en.wikipedia.org/wiki/Twisted_pair No Shielding [UTP] Cable shielding [F/UTP] Pair shielding [F/FTP] 93 ENEL712-Embedded Systems Design Maximum Transmission Distance • A multitude of factors make up the maximum transmission distance of a communications interface – – – – – – – Voltage Level Data rate (bandwidth) Single vs Differential Signalling Cable Construction Cable Capacitance Impedance Matching Expected External Noise (EMI) • Generally: The reliable distance is inversely related to the data rate Standard Max Length RS-232 15m @ 19,200bps RS-422 1.2km @ 100,000bps RS-485 1.2km @ 100,000bps TTL RS-232 Hard to Say, 5m @ 50kHz maybe SPI / I2C Hard to Say, 10m @ 100kHz maybe USB 3.0 3m – The faster the data rate, the shorter your communications channel (cable/PCB track) should be 94 ENEL712-Embedded Systems Design Advanced Communication Interfaces • We have already seen in both RS-232 and I2C how extra bits are added to synchronise communications • Once we get to high-speed, advanced communication interfaces, many more bits are added to improve the robustness of the interface – This is true of CAN, but also other common interfaces such as USB • This makes the protocol much more complicated, and thus implementing it to be much more time consuming – The reward is however a higher data rate, which can make or break a product – Imagine a Go-Pro that downloads videos at the same rate as playback! • Many MCUs now include hardware and free software (stacks) to allow you to use advanced communication interfaces, such as USB and TCP/IP 95 ENEL712-Embedded Systems Design USB Overview • Universal Serial Bus (USB) is an industry standard that defines the cables, connectors and protocols used to provide communication and power between computers and electronics devices – Developed in the 1990s to standardize the connection of computer peripherals • USB has evolved through multiple standards – from 1.0 to 3.1 (and soon C) – Data rates from 1.5Mbps to 10Gbps • Host controlled, tiered star topology – Maximum of 127 devices per host – Normally hubs are used to expand the number of physical ports • Serial Communication! – – – – Differential Signalling using Shielded Cable USB 1.0->2.0 only 4 wires (DP, DM, Vcc & Ground) USB 3.0 11 wires USB C 24 wires [see the increasing complexity?] 96 http://en.wikipedia.org/wiki/USB ENEL712-Embedded Systems Design USB Architecture • A single USB system comprises of a USB host and one or more USB devices – – • USB 2.0 is a unidirectional broadcast system – all downstream devices receive all traffic – – • All devices on a USB system must share the bandwidth available by the host • USB Spec is a maximum of 7 tiers within topology There can be hubs as well Devices have speed categories, even within a particular standard To communicate with a specific device, a host must send an address in the token packet Low and high speed devices will receive packets only at their respective speeds http://www.totalphase.com/support/articles/200349256-USB-Background 97 ENEL712-Embedded Systems Design AT90 MCU USB (Double Buffered) • The AT90USB contains a USB peripheral that can act as a Host or Device – It contains 6 endpoints that can be used to transfer data to/from • While the hardware takes care of the USB packets, you must still have a solid understanding of the protocol in order to set up and use USB with an MCU – Don’t forget you will also need a custom application on the PC side to send information over USB! 98 Convinced a UART is easier yet? ENEL712-Embedded Systems Design ASF-USB • Generally, if you are just getting started with USB on an MCU, it is suggested you use a Stack – A software library designed to interface with a manufacturer’s hardware • Atmel provides a large number of example Stacks to support various USB modes and devices – These are free! – Included by default with Atmel Studio • Stacks exist for many common peripherals, not just USB! 99 ENEL712-Embedded Systems Design Ethernet (Local Area Networks) • If you thought USB was complicated, wait until you see Ethernet and the Internet Protocol (IP)! • Ethernet is actually a family of computer networking technologies – Normally we think of 100BASE-T (or 1000), i.e. a Network port with 100 or 1000Mbps transfer rates over twisted pair cables • Ethernet is one of the most ubiquitous communications technologies used today – And therefore interoperability opportunities with other systems is huge (e.g. over the internet) – Hence the “Internet of Things” • I’m not going to explain how Ethernet and IP works (you can learn that in a communications course) – But it is interesting to see how Ethernet can be used with an MCU 100 ENEL712-Embedded Systems Design Ethernet Controllers • Generally, most 8/16 bit microcontrollers do not come with support for Ethernet – – – • Therefore, an Ethernet Controller can be implemented to do the ‘hard work’ – • They don’t have the RAM or processing speed to keep up A lot more internal hardware is required! Some Atmel ARM processors do, but not all Microchip, another IC manufacturer, makes several variants As well as an Ethernet Controller, you will also need the ‘magnetics’, i.e. the transformers required to connect to the RJ-45 socket Microchip also provides a free TCP/IP stack to suit the above, making it “easy” with PIC MCUs to get started 101 http://ww1.microchip.com/downloads/en/DeviceDoc/39662e.pdf ENEL712-Embedded Systems Design Ethernet: Use an OS! • Realistically, if you want to use Ethernet in a project, you will want to use an Operating System (OS) – • A Raspberry Pi is only $40 – try building something cheaper with similar performance! – – • Obviously not a production solution, but Linux can be used with many ARM processors Hint – Ethernet with an 8bit MCU is just hard work! Alternatively you can buy modules that handle the Ethernet complexities for you, and you just talk to it via SPI/UART – • Linux comes with drivers to handle the low-level hardware communications & protocols for you No benefit in terms of data rate, but definitely increased connectivity There are also MCU boards that come with Ethernet + a built in Stack which provide simple Ethernet functionality (Tx, Rx, Connect, etc) – http://www.ethernut.de/ WIZ812MJ XPort MiiNEPort E3 102 ENEL712-Embedded Systems Design Advanced Communication Interfaces: My Advice • Beyond UARTs, SPI and I2C, communications gets very complicated, very quickly – We could spend a whole semester on USB alone • Generally USB is used once data rate becomes an issue – E.g. downloading of measured data • Ethernet is normally used for increased connectivity with existing systems – Talk to the device via existing PCs or even the Internet • There are a lot of work arounds to make the above simpler – Manufacturer provided Stacks – Add on 3rd party modules – Integrated MCU support 103 ENEL712-Embedded Systems Design Lecture References • Microcontroller Systems 2015 – • USB in a NutShell – – • http://www.microchip.com/stellent/groups/sitecomm_sg/documents/devicedoc/en551260.pdf © Microchip AT90USB1287 Datasheet – • http://www.totalphase.com/support/articles/200349256-USB-Background © Total Phase Embedded Ethernet Solutions – – • http://www.beyondlogic.org/usbnutshell/usb1.shtml © Beyond Logic USB Background – – • © Mark Beckerleg & Alan Smith © Atmel Atmel Embedded Web Server AVR460 – – http://www.atmel.com/Images/doc2396.pdf © Atmel 104 Lecture 7 Embedded Hardware Design ENEL712-Embedded Systems Design Embedded Specifications Example • You are given a specification: – “Design a remote weather station for use in NZ vineyards” • It must be able to be monitor and record temperature, humidity, rainfall, sunlight hours. • It must be self-powered (or minimize battery replacement) • It must communicate wirelessly to the owner’s house • Normally brief, lacking technical detail – A lot of assumptions could be made about the above! • • • • • • Size? MCU? Choice of wireless technology? Distance? Power supply? Sample rate? This Lecture: We will look at the hardware design – Next week we will look at the technical software design 106 ENEL712-Embedded Systems Design Embedded Hardware Design • Normally an iterative process – – – – – – – – – – What MCU will we use? What type of power supply will we use? Surface mount or through hole components? How many layers will my PCB be? Communication interfaces? I/O (Sensors, Displays, Buttons?) Software requirements? Environmental conditions? Component & manufacture cost? Etc, etc, etc • Generally, I recommend getting a piece of paper and drawing a block diagram 107 ENEL712-Embedded Systems Design Specification Block Diagram power-supply battery temperature humidity display μC rainfall sunlight JTAG header memory wireless 108 ENEL712-Embedded Systems Design OK – We Have a Block Diagram • What next? – Start the design process! • There are three main categories of design choices: – MCU Selection – I/O Devices – Power Supply Design • Which should we do first? – Does it matter? – YES! Normally I/O devices are chosen first 109 ENEL712-Embedded Systems Design I/O Devices • We can further divide I/O devices into: – Sensors • Environment measurement such as temperature, light, movement – Actuators • Motors, solenoids, speakers – User Input Which ones do we need to consider for our weather station? • Buttons, keypads – Displays • LCDs, LEDs – Communications • SPI, UART, USB, Ethernet, Wireless – Storage • External Memory, EEPROM, SDCard Don’t forget the JTAG/ISP! 110 ENEL712-Embedded Systems Design Research Time! • Unless specified, you will need to find I/O devices that meet your specifications – It is not unusual that you have not worked with a sensing technology or I/O device before • Your best friends are going to become: – Element14 • http://nz.element14.com/ – Digikey My recommended sites • http://www.digikey.co.nz/ – RS Components • http://nz.rs-online.com/web/ – Soanar • http://www.soanar.com/ – Mouser • http://nz.mouser.com/ – Jaycar (sometimes) • http://www.jaycar.co.nz/ 111 ENEL712-Embedded Systems Design Temperature Sensor Example • Element14: – – Look under temperature sensors and we find the normal analogue variety… However let’s see if we can find a digital one! • – • Easier to read accurately (no analogue considerations) Under Semiconductors – ICs / Sensors • – Success! Select In Stock! Considerations: – Preferably digital (also consider resolution) SMD / Package? • – Through hole for external sensing Voltage? • 3.3->5VDC – Temperature Range? – Temperature Accuracy? • • – At least -10°C to 50°C At least 1°C Dynamic Response? • – Digital Output Type? • – Analogue At least 1Hz MICROCHIP TCN75AVUA. TEMP SENSOR, 2WIRE S, 2.7V Maybe? Cost & Availability? 112 http://nz.element14.com/microchip/tcn75avua/temp-sensor-2wire-s-2-7v-8msop/dp/1627191 ENEL712-Embedded Systems Design Wireless Communications Example • Element 14 – While we could buy a Transceiver IC, it is much easier to buy a module with built in Antenna • • Antenna design, coupling, and impedance matching cannot be ignored, thus if you can buy it already configured, do so! Considerations – Communication Range • Min 1km – Communications Protocol • Point-to-point, Mesh, Multi-drop? – Data Rate • 100Kbps should be OK – Operating Frequency & Tx Power • Preferably ISM Band – Voltage & Power Requirements • 3.3->5VDC and min power – Module or IC? • DIGI INTERNATIONAL XBP24-Z7SIT004 ZIGBEE MOD, XBEE PRO ZB, RPSMA CONN Maybe? Module – avoid Antenna design! – Physical Size • Small! – MCU Interface • UART or SPI preferably – Cost & Availability http://nz.element14.com/digi-international/xbp24-z7sit-004/zigbee-mod-xbee-pro-zb-rpsma-conn/dp/1751800 113 ENEL712-Embedded Systems Design I/O Tally • Once all the I/O devices have been decided, you can tally the required I/O for the microcontroller • Normally this is: – – – – – – – – – # Digital Inputs Digital # Digital Outputs I/O # Analogue Inputs Analogue I/O (ADC, # Analogue Outputs DAC) # UARTs Communication # SPIs Interfaces # I2Cs # PWM Channels Timers # Input Capture Channels 114 ENEL712-Embedded Systems Design Microcontroller Selection • Once you have a fair idea what I/O your project will require, you can choose your microcontroller (at least the first iteration) • Remember we also need to take into account: – Power supply requirements • Voltages available, low power modes? – CPU/Memory • Large program and/or computationally intensive? – Built in Peripherals & Features • Required hardware peripherals and built in functionality like DMA? – PCB Considerations • SMD, multi-layer PCB, decoupling capacitors, external components? – Price & Availability • How much is it and can you buy it? – Compiler & Programmer • Do you have the tools to develop with this microcontroller? – Familiarity • Is there a steep learning curve? 115 ENEL712-Embedded Systems Design Microcontroller Selection Example • For the purposes of this example, let’s assume we require the following I/O: – 5x Digital Outputs (Empty Rainfall Container + Battery Charger + Power Down Lines + SS line) – 3x Analogue Inputs (Rainfall + Sunshine + Voltage) – 1x UART (Wireless Communications) – 2x I2C (Temperature + Humidity) [but on a bus] – 1x SPI (EEPROM) • In addition (from experience) – Low power is a bonus • But sleep modes are more useful – Lower voltage • Better for battery powered – Something from Atmel is preferred • Already have the tools and knowledge – SMD • Smaller PCB – Not a lot of processing • So 8 bit will be fine 116 ENEL712-Embedded Systems Design MCU Selection [1] • Always best to start at the manufacturer’s website – Their product search is usually better than the component suppliers http://www.atmel.com/v2pfresults.aspx#(actives:!(),data:(area:'',category:'34864',pm:!(),view:list),sc:1) Still 131 MCUs to choose from! 8 bit AVR >=1 >=1 >=1 No 0 117 0 ENEL712-Embedded Systems Design MCU Selection [2] • The remainder of our MCU choices come down to: – – – – – – Memory Requirements Operating Frequency Operating Voltage Pin Count Special Functionality (such as low power options) Cost & Availability This will be the main driver in this application 118 ENEL712-Embedded Systems Design MCU Selection [3] • Use Element14 to narrow down a possible MCU based on the family identified using the Atmel product finder – Restrict further by case style (SMD) and availability (In Stock) – Order by Price and find a suitable candidate Maybe? Chosen primarily due to PicoPower mode ATmega 328P (picoPower version) - 32KB Flash - 2KB RAM - 1.8V – 5V operation - All required peripherals But NO JTAG! http://nz.element14.com/atmel/atmega328p-au/mcu-8bit-atmega-20mhz-tqfp- 119 32/dp/1715486 ENEL712-Embedded Systems Design MCU Selection • The last thing to check is take the MCU pinouts and cross off what they are used for – • This double checks you have enough I/O! How many spare I/O lines do we have on this MCU? 5x Digital Outputs 3x Analogue Inputs 1x UART 2x I2C [but on a bus] 1x SPI Have we forgotten anything? ISP! http://www.atmel.com/images/doc0943.pdf 120 ENEL712-Embedded Systems Design Power Supply Design • With the I/O devices and MCU decided, we can start designing the power supply – Normally always DC -> DC • Considerations: – Input Voltage • Remember to take into account the min and max Vin! – Output Voltage(s) • You may require multiple output voltages – Noise • Embedded circuits are very susceptible to noise! • Especially MCUs! – Current • How much current will your product require (per Voltage rail)? – Efficiency • Is efficiency a concern? – Protection • Over current, under and over voltage, over temperature? – Heatsinking • Will components get too hot without a heatsink? – Component Cost & Availability 121 ENEL712-Embedded Systems Design Draw a Block Diagram & Tally the Required Current • Include the Supply, Voltage Regulators and Loads 380mA Battery 1mA 5V Regulator 100mA Light sensor Rainfall sensor e.g., LiPO 5.4~8.4V MCU 3.3V Regulator Temperature Sensor Humidity Sensor Device Voltage Current MCU 3.3V 10mA Wireless 3.3V 205mA EEPROM 3.3V 20µA Temp 3.3V 200µA Humidity 3.3V 200µA Sunshine 5V 1mA Rainfall 5V 100mA Wireless T/R Total 5V Total 3.3V calculated 101mA 216mA 20% margin 121mA 260mA Total 380mA EEPROM 122 ENEL712-Embedded Systems Design Switching or Linear Regulator? • A choice you will commonly need to make is whether to use exclusively linear regulators, or whether to use switching regulators as well • Normally the decision to use a switching regulator is based on: – Large voltage difference between Vin and Vout • – – Vin is less than require Vout Efficiency is a critical design requirement • • Switching regulators often exceed 80% efficiency However, using a switching regulator is more complicated, and normally always induces LOTS of noise into the power supply rails – • Poor linear regulator will get hot here! Also very inefficient. This can cause havoc in an embedded system The solution is to use a switching regulator as the first stage of the power supply, followed in series by one or more linear regulators – – The linear regulators + decoupling capacitors remove most if not all of the noise Still requires a careful design 123 ENEL712-Embedded Systems Design Regulator Selection [1] • For this example we are going to select the 3.3V regulator – We know we need it to supply at least 260mA, and a drop out voltage < 1.7V • Back to Element 14 under: – Semiconductors – ICs -> Power Management 124 ENEL712-Embedded Systems Design Regulator Selection [2] • Narrow down as many choices as possible by: – – – – • Fixing the output voltage Selecting a minimum and maximum output current Selecting a maximum dropout voltage In Stock! Note however we still have 88 options! – Now start looking by Vin, cost [cheap], availability and package [something with pins!] 125 ENEL712-Embedded Systems Design Regulator Section [3] • At this point virtually all regulators left will fulfil the job required – Preference comes down to packaging and cost normally Maybe? 126 http://nz.element14.com/microchip/mcp1824t-3302e-ot/ic-ldo-3-3v-300ma-sot-23-5/dp/1578387RL ENEL712-Embedded Systems Design What Next? • Start your schematic design! – Most of your components should hopefully be in the AUT Altium Library • If not, ask the technicians at technical support to make the component for you • Follow the datasheets – Most datasheets have design tips, required external components, and PCB layout suggestions • Get your design checked during Technical Support – If your supervisor is OK with it first • Start planning your software! – You don’t need the hardware to start programming 127 ENEL712-Embedded Systems Design Lecture References • Embedded Systems 2014 – © Mark Beckerleg & Alan Smith • Microcontroller Systems 2015 – © Mark Beckerleg & Alan Smith 128 Lecture 8 Embedded Software Design A: Software Engineering (1 of 4) ENEL712-Embedded Systems Design Software Engineering • Formal Definition: – “Software engineering is an engineering discipline that is concerned with all aspects of software production” • What is Software? – Computer (and embedded system) programs and associated documentation. • Note the requirement to be run on a ‘computer’ is no longer valid. • Realities of Software – More and more systems are software controlled – Software costs often dominate computer system costs. The costs of software on a PC are often greater than the hardware cost. • This is also often true for embedded systems! – Software costs more to maintain than it does to develop. For systems with a long life, maintenance costs may be several times development costs. 130 ENEL712-Embedded Systems Design Software Process Activities (1) • Software Specification – Where customers and engineers define the software that is to be produced, and the constraints on its operation 131 http://dilbert.com/strips/comic/2006-01-29/ ENEL712-Embedded Systems Design Software Process Activities (2) • Software Development – Where the software is designed and programmed 132 http://www.datamation.com/news/tech-comics-software-development-2.html ENEL712-Embedded Systems Design Software Process Activities (3) • Software Validation – Where the software is checked to ensure that it is what the customer requires http://cartoontester.blogspot.co.nz/2012_02_01_archive.html 133 ENEL712-Embedded Systems Design Software Process Activities (4) • Software Evolution – Where the software is modified to reflect changing customer and market requirements http://living-websites-cloud.eu/blog/what-does-agile-and-scrum-software-development-mean/ 134 ENEL712-Embedded Systems Design Software Requirements 135 ENEL712-Embedded Systems Design “Requirement” Definition • A requirement may range from a high-level abstract statement of a service or of a system constraint to a detailed mathematical functional specification. • This is inevitable as requirements may serve a dual function: – They may be the basis for a bid for a contract and therefore must be open to interpretation. – Or they may be the basis for the contract itself and therefore must be defined in detail. – Both these statements may be called requirements. 136 ENEL712-Embedded Systems Design The Cost of Getting the Requirements Wrong http://www.aviamedia.com/aviamedia-requirements-engineering.html 137 ENEL712-Embedded Systems Design Where to Bugs come From? Mogyorodi, G. (2003) What is Requirements Based Testing? The Journal of Defense Software Engineering, 12-15. http://mcnickle.org/are-you-testing-your-software-too-late-in-theprocess/ 138 ENEL712-Embedded Systems Design Types of Requirements [1] • Functional Requirements – Statements of services the system should provide, how the system should react to particular inputs and how the system should behave in particular situations. – These may also state what the system should not do. – Describe functionality or system services. – Depend on the type of software, expected users and the type of system where the software is used. • Functional user requirements may be high-level statements of what the system should do. • Functional system requirements should describe the system services in detail. 139 ENEL712-Embedded Systems Design Types of Requirements [2] • Non-Functional Requirements – Constraints on the services or functions offered by the system such as timing constraints, constraints on the development process, standards, etc. – These often apply to the system as a whole rather than individual features or services. – Define system properties and constraints. • e.g. reliability, response time and storage requirements. – Constraints are I/O device capability, system representations, etc. – Process requirements may also be specified mandating a particular IDE, programming language or development method. • Non-functional requirements may be more critical than functional requirements. If these are not met, the system may be useless. 140 ENEL712-Embedded Systems Design Software Modelling via UML • System modelling is the process of developing abstract models of a system, with each model presenting a different view or perspective of that system. • System modelling has now come to mean representing a system using some kind of graphical notation, which is now almost always based on notations in the Unified Modelling Language (UML). • System modelling helps the analyst to understand the functionality of the system and models are used to communicate with customers. • Models of the new system are used during requirements engineering to help explain the proposed requirements to other system stakeholders. Engineers use these models to discuss design proposals and to document the system for implementation. We will not cover UML in this course – but be aware of it 141 ENEL712-Embedded Systems Design Abstraction • Abstraction: Suppressing or ignoring some properties of objects, events, or situations in favour of others. – Abstraction is an important problem-solving technique, especially in software design. • Importance of Abstraction – Problem Simplification: Allows us to focus on the most important aspects of a problem in (partially) solving it – Structuring Problem Solving • Top-Down: Solve an abstract version of the problem, then add details (refinement) • Bottom-Up: Solve parts of a problem, and then connect them for a complete solution. • Time and time again I remind students to not attempt to solve the whole problem at once, but rather focus on core parts (modules) – This applies for all projects, but especially software projects 142 ENEL712-Embedded Systems Design Use of Graphical Models • As a means of facilitating discussion about an existing or proposed system – Incomplete and incorrect models are OK as their role is to support discussion. • As a way of documenting an existing system – Models should be an accurate representation of the system but need not be complete. • As a detailed system description that can be used to generate a system implementation – Models have to be both correct and complete. 143 ENEL712-Embedded Systems Design State Machine Models • These model the behaviour of the system in response to external and internal events. • They show the system’s responses to stimuli so are often used for modelling real-time systems. • State machine models show system states as nodes and events as arcs between these nodes. When an event occurs, the system moves from one state to another. • Statecharts (state diagrams / state machines) are an integral part of the UML. 144 ENEL712-Embedded Systems Design Microwave State Diagram UML State Diagram 145 ENEL712-Embedded Systems Design Microwave Sub-State Diagram • State diagrams can consist of “Superstates”, which can be expanded into sub-state diagram 146 ENEL712-Embedded Systems Design Software Testing & Bugs http://softwaretestingandqa.blogspot.co.nz/2007_12_01_archive.html 147 ENEL712-Embedded Systems Design Software Testing (1) • Testing is intended to show that a program does what it is intended to do and to discover program defects before it is put into use. • When you test software, you execute a program using artificial data (typically). • You check the results of the test run for errors, anomalies or information about the program’s nonfunctional attributes. • Testing can reveal the presence of errors, NOT their absence 148 ENEL712-Embedded Systems Design “Finding Bugs” http://onlinefungags.com/2012/10/software-testing-metrics/ 149 ENEL712-Embedded Systems Design Software Testing (2) • Testing is part of a more general verification and validation process • The goals of program testing are: – To demonstrate to the developer and the customer that the software meets its requirements. • There should be at least one test for every requirement in the requirements document. – To discover situations in which the behavior of the software is incorrect, undesirable or does not conform to its specification. • Defect testing is concerned with identifying undesirable system behavior such as system crashes, unwanted interactions with other systems, incorrect computations and data corruption. 150 ENEL712-Embedded Systems Design Validation and Defect Testing • The first goal leads to validation testing. – You expect the system to perform correctly using a given set of test cases that reflect the system’s expected use. A successful test shows that the system operates as intended. • The second goal leads to defect testing. – The test cases are designed to expose defects. The test cases in defect testing can be deliberately obscure and need not reflect how the system is normally used. A successful test is a test that makes the system perform incorrectly and so exposes a defect in the system. 151 ENEL712-Embedded Systems Design Software Engineering Summary • Most of the principles of “pure” software engineering apply to developing software for embedded systems • Remember the four main software process activities – Specification, Development, Validation, Evolution • Software is still normally the largest development cost in embedded systems – Do not underestimate the effect of bugs! • Next lecture we will look at practical software design for embedded systems 152 ENEL712-Embedded Systems Design Lecture References • Embedded Systems 2014 – © Mark Beckerleg & Alan Smith • Microcontroller Systems 2015 – © Mark Beckerleg & Alan Smith • Introduction to Software Engineering Design: Processes Principles and Patterns with UML2 – Christopher Fox – © Addison-Wesley 153 Lecture 9 Embedded Software Design B: Architectural Design (2 of 4) ENEL712-Embedded Systems Design Embedded Software Development • Developing Software for an Embedded System requires knowledge of the hardware as well – Therefore as Electrical & Electronic Engineers, you have the best combination of skills to assist you developing the software • Software development is iterative – You are very unlikely to get the design right the first time, no matter how much experience you have • The more software / embedded projects you do, the easier (and hopefully more fun) writing the software will become – Not only will you understand C/C++ better, but you will have template projects to go back to, to reference – You will also understand better the hardware peripherals and MCUs • There is no ‘one size fits all’ solution to writing embedded software – Different architectures, different languages, and different hardware all mean you need to decide the best tools for the individual specification – The decision of what to use comes from experience 155 ENEL712-Embedded Systems Design Embedded Programming Languages 2010 Embedded Engineer Survey http://blog.vdcresearch.com/.a/6a0115714871cc970c0134875578fa970c-pi 156 ENEL712-Embedded Systems Design Bottom-Up or Top-Down Approaches • Effectively, there are two ways software can be developed: Bottom-Up Top-Down Bottom-up software development starts by development of the low-level modules: - For embedded systems, these could be communication drivers or display drivers Top-down software starts by planning the complete system at a high-level, and successively adding detail as development progresses - For embedded systems, this would be the system architecture Advantages: - Get coding quickly, and the ability to test modules and hardware quickly Disadvantages: - No clear picture of the overall system/software design. - The interfaces between modules are not defined, nor is the system architecture. - The complexity of the software increases with each module, often in an uncontrolled fashion Advantages: - The entire system is defined before coding starts, thus major code changes later are less likely - As detailed is added, the function of low-level modules becomes obvious, thus the coding of them should be easier Disadvantages: - Cannot test anything until midway through development Modern software design approaches normally combine elements of both bottom-up and top-down. However it considered poor form (and risky!) to start coding without a clear picture of the complete system architecture. 157 ENEL712-Embedded Systems Design Embedded Software Architectures • The architecture of a software program is: – The program’s major parts – The responsibilities and properties of each part – The relationships and interactions between the parts • Architectural design should be the first step in any software project – Note this is a software only view, for embedded systems software often depends on the hardware chosen, thus can be done in parallel – Done correctly, architectural design can reduce or eliminate the need for major code changes later – It does however require substantial experience to do correctly the first time 158 ENEL712-Embedded Systems Design Architectures [1] : Polling Loop • Polling is the simplest strategy for implementing embedded software • The program repeatedly runs a loop of code that checks all inputs and handles all actions required • Often a delay is used to avoid the loop running too quickly – Alternatively a flag from a timer can be used to synchronize the polling loop while(1) { if(in1) doAction1(); else if(in2) doAction2(); • If delays are used, the processor is effectively stalled, wasting cycles – Not power or computationally efficient } _delay_ms(100); 159 ENEL712-Embedded Systems Design Architectures [2] : Event Driven • An event driven architecture uses internal or external events to trigger data to be processed within the program • Generally these events are interrupts – Timer, communication, or other peripheral • Between events, the processor is free to complete other tasks – Or go to sleep to reduce power • Architectures with many interrupts can become complicated – Thus using interrupts for high priority tasks and polling for low priority can be a suitable solution while(1) { if(dataRx) processData(); else sleep(); } … ISR(CommVect) { … dataRx = 1; } 160 ENEL712-Embedded Systems Design Architectures [3] : State Machine • A State Machine divides the program into a set of states (tasks) which are transitioned (switched) between based on internal or external events • The program knows the current state of the system, and performs the task(s) corresponding to this state • When an event occurs (e.g. button press, timer expired), the system state changes to another state, based on the allowable transitions • State machines are also known as Finite State Machines (FSM), which have a finite number of possible states – Widely used in embedded software – Normally implemented as a switch-case statement switch(state) { case INIT: doInit(); case RX: doBuffer(); case STOP: doStop(); } 161 ENEL712-Embedded Systems Design Architectures [4] : Operating System • An Operating System (OS) is software that manages hardware and software resources and provides services for user applications • Within an embedded system, the OS is often a cut-down version of a PC OS, due to the limited memory and CPU performance • At the heart of an OS is the Kernel, which controls the other OS components such as Networking and File System • Often an OS will allow multiple tasks to run, and allocate computation time between them (time slicing), resulting in the effect of parallelism on a single core • An OS is often used when more advanced peripherals like USB, Ethernet, and File Systems are required, as they have built in drivers to support them • Strictly speaking, an OS (vs an RTOS) does not guarantee any timing requirements of the user application 162 http://www.embedded-systems-portal.com/CTB/Embedded_Operating_System,1002.html ENEL712-Embedded Systems Design Architectures [5] : Real-Time Operating System (RTOS) • A Real-Time OS (RTOS) is an OS designed to operate in real-time – • All data must be processed in real-time, without buffering delays There are two types of Real-Time Systems: – – Soft, where timing is not that critical Hard, where all timing constraints must be enforced • An RTOS must be able to run a user application deterministically, i.e. within a known execution time that is independent of other tasks currently executing • RTOS are normally deployed to embedded systems, rather than OSs, due to the time critical nature of most embedded control applications • Note Windows and (standard) Linux are not RTOSs – RTLinux, FreeRTOS, SYS/BIOS, WindowsCE are 163 http://en.wikipedia.org/wiki/Real-time_operating_system ENEL712-Embedded Systems Design Hardware / Software Partitioning • There is usually some choice between implementing features in hardware or software • Generally hardware is cheaper, faster to develop, and runs faster • Software has a lower manufacture cost, because other than memory, it costs nothing to reproduce per device • Examples of partitioning choices – – – – – • Switch debouncing UART/SPI/I2C via hardware or bit-bang Encoding / Decoding Encryption / Decryption Timing Use built in hardware where available – – – – DMA Event Systems Timer driven peripherals Communication ports 164 ENEL712-Embedded Systems Design Fault Tolerant Code • Embedded systems need to be able to recover automatically from faults – For example, if a power spike interferes with system operation, the system should be able to recover without operator intervention • Unless the hardware is damaged! • Simple techniques can be used to increase the tolerance of your embedded code to errors: – Power-On-Self-Test (POST) • Check all components are operating correctly • Any values in memory have sensible values – Checksums • Calculate a checksum of all stored values (settings, for example) and ensure it is the same as a pre-calculated value – Hardware Initialization • Don’t rely on the microcontroller hardware to always initialize all ports to the data sheet specification • Typically, this falls in to the realm of “Defensive Software Design” 165 ENEL712-Embedded Systems Design Defensive Software Design • There are many techniques that can reduce the damage caused if interference changes the operation of a program – Software runaway may occur where the program goes to a random location and executes code it finds there • Useful techniques include: – Update registers as part of normal program operation, not just in a setup routine – Boundary check variables to see what range is acceptable – Fill unused memory with code that will end up in a safe routine (nop) – Define all unused interrupt vectors to a safe routine – Disable interrupts while modifying hardware registers – Use a watchdog timer to automatically reset the program if it was to get ‘stuck’ 166 ENEL712-Embedded Systems Design Software Documentation • Documenting software, whether for a PC or an embedded system, is critical to the maintainability of the code – – • Remember the last software process – evolution! Inevitably the code will be modified again, due to changing customer requirements, bugs, new hardware, or even as the template for a new product/project Documenting software can be done in a multitude of ways: – – – Sensible variable and function names (not var, fcn, x, y) Commenting! One of the reasons we get you to comment Graphical diagrams • • • – – • Mathematical Equations Technical Manual Remember documentation is not just limited to software – – • State diagrams (my favourite) Flow charts UML diagrams (4th year) No matter which industry you end up in (power, communications, embedded, etc), you will be documenting your projects Documentation can be a legal requirement in many engineering professions Get in that habit now of documenting as you go, via comments and diagrams 167 ENEL712-Embedded Systems Design Lecture References • Embedded Systems 2014 – © Mark Beckerleg & Alan Smith • Microcontroller Systems 2015 – © Mark Beckerleg & Alan Smith • Embedded Operating Systems – CTB Embedded Systems – http://www.embedded-systems-portal.com/CTB/Embedded_Operating_System,1002.html 168 Lecture 10 Embedded Software Design C: Modularizing Projects (3 of 4) ENEL712-Embedded Systems Design Modularizing Software • Once you get past flashing an LED you need to start considering how to best divide up your program – Known as modularizing – Multiple source files, classes and functions • Modularizing allows you to group common software functionality into modular functions or objects – We will talk about objects after the break • Modules may be interchangeable, or they may be unique – The point is the software within a module is designed to meet the modules functionality, not the entire project • This is a key component of architectural design http://en.wikipedia.org/wiki/Modular_programming Applies to hardware too! 170 ENEL712-Embedded Systems Design Modularizing Concept Project Specification Module [1] Conceptual Module [2] Implemented Source File [1A] Function [1A-1] Function [1A-2] Source File [1B] Function [1B-1] Source File [2A] Function [2A-1] Function [2A-2] Note this methodology only applies as above to procedural programming (e.g. C) – we will revisit this in Object Orientated Programming 171 ENEL712-Embedded Systems Design Defining Modules • Think of modules as categories of software functionality – Communications Module, Controller Module, UI Module • The task is not to think so much in terms of source code, but in an abstract, high-level grouping of common functionality • It is the first step where you begin to identify the required components from your project specification – 3-5 modules are usually sufficient, depending on the complexity of the project • Think back to our Vineyard Wireless Sensor – What modules would we have? 172 ENEL712-Embedded Systems Design Multiple Source Files • For each module, it can be implemented in software as one or more source files – • Using multiple source files within a project allows you to develop and test individual components in isolation – • – The ability to control access to functions (methods) and variables (data). Unless declared in a header file, variables and functions are only accessible in the local source file. Data and methods to operate on that data are grouped within a common file/object. The easiest solution is to have one source file per module – • It also provides a more defined system architecture Multiple source files also allow a basic form of encapsulation – • In OOP these could be objects However there may be times where more than one source file is more logical An example of the different source files in my Assn 2 solution Take the Sensor Module in our Vineyard sensor, how many source files would we need? 173 ENEL712-Embedded Systems Design Multiple Functions • For each source file, you will have one or more functions – Typically more than one! • Each function performs one small part of the required functionality – E.g. for the assignment, don’t read the whole GPS sentence in one function, but use multiple functions to read each parameter • Adding multiple functions allows you to further divide your software into smaller, easier to write, easier to test and easier to maintain chunks • Keep in mind too many functions is also inefficient An example of the different functions within the gps source filesin my Assn 2 solution – There is no correct number, but 3-6 per source file is fine • Take the Sensor Top-Level Source File in our Vineyard example, what functions would we have? 174 ENEL712-Embedded Systems Design Advantages of Modularizing • There are many advantages to modularizing: – Promotes better software architecture by encouraging top-down design – Project functionality is logically divided between source files and functions, making software easier to: • • • • Develop (well-defined tasks) Debug (problem areas are narrowed down faster) Test (smaller functions = easier to isolate and thus test) Maintain (logical divisions make understanding code easier, and thus updating easier) – Code can be reused within other projects, if written in a sufficiently general way 175 ENEL712-Embedded Systems Design Disadvantages of Modularizing • Some of the disadvantages: – More source files creates more clutter – Finding implemented functionality can be more difficult if looking across multiple files – Header files are now required to link functions between source files – Your code is could be less efficient when run, depending on how the compiler implements it • Lots of jumping between functions means lots of pushing and popping on the stack 176 ENEL712-Embedded Systems Design Other Techniques: Mid & High-Level Drivers • Consider the following prototype: – uint8 readSPIReg(uint8 device, uint8 address) • The above implements an SPI read for a specified device (i.e. an enum perhaps) with a given register address, and returns the data read – The user does not have to worry about SPI registers, SPI data exchanges, or any specifics of the communication interface – It works for multiple devices, and thus could be used no matter how many SPI devices are connected – Mid-Level Driver • Mid-Level Driver Levels [note the modularization!]: – Low-Level – Register Level (e.g. SPDR) – Mid-Level – Send/Receive Individual Bytes – High-Level – Perform specific functionality • High-Level Consider the AUT library, which driver level is implemented? I typically use this technique for all my MCU communication interfaces (Arduino Type Approach) – Simplifies Code! Low-Level Note High calls Mid which calls Low 177 ENEL712-Embedded Systems Design Other Techniques: “Wrapper” Functions • Sometimes you will have complex functions which you may have to call frequently – Setting up the required data for every call can be tedious • A wrapper simplifies the calling of a complex function, by providing a simpler calling interface – This could set default values automatically, or accept a more user-friendly argument list and perform the conversion internally • • Wrapper Function Wrappers are common when interfacing between different programming languages, or using 3rd party code Note a wrapper doesn’t change the functionality of the original function, it just makes it easier to call Original Complex Function Similar in concept to the multiple driver-levels for I/O devices 178 ENEL712-Embedded Systems Design Modular Design “Recipe” • Modular Code Design normally requires a top-down approach – Plan the architecture first • However it doesn’t have to be done this way, you could treat each I/O device as a module, and write code for them as you go – Thus a bottom-up approach • For this course, I want you to think of modular design as a top-down software design approach – The following slides illustrate one method of designing modular code in your own projects – There are many variations, which you will see in OOP and 4th year software engineering – There is no one right solution! 179 ENEL712-Embedded Systems Design Modular Design Step 1: Module Identification • From the project specification, divide the required functionality into 3-5 main groups – These groups could be: • • • • • Physical devices e.g. hardware User I/O e.g. menus, buttons Algorithmic e.g. a control algorithm Data e.g. GPS sentences Some ideas on how to do this: – Use a flow chart showing how data is gathered, processed, and output by the system, then group together logical units – Pretend you are dividing the project up as a group and think about ways it could be split amongst the group members – Use physical divisions such as size or location – Use standard design patterns from software engineering • Remember Module Identification is a conceptual phase, you are not yet thinking in code 180 ENEL712-Embedded Systems Design Modular Design Step 2: Source File Identification • For each module identified, determine how many source files are required – Typically 1, sometimes more • Some ideas on how to do this: – Consider the scope of the module, if it is going to require lots of code and therefore lots of functions, then perhaps 2+ source files are better – Look for divisions based on hardware • E.g. a Sensor Module might have 3 complex sensors, thus 3 source files might be appropriate • Remember that software design is iterative – the decisions you make now are flexible later 181 ENEL712-Embedded Systems Design Modular Design Step 3: Function Identification • For each source file identified, determine how you will divide the required functionality between software functions – Remember writing functions serve multiple roles: • They replace repeatedly called code with a single implementation • They divide up a program into more manageable chunks • Some ideas on how to do this: – Create a flowchart on how data is processed to meet the source file’s functionality requirement • Each step within the flowchart can be a function – If using a state-machine, each major state could be a function – Repeated functionality • Never copy and paste code – use a function! – Wrappers / Higher-Level driver identification • As before, this part is still iterative. Often I add new functions and modify the roles of existing ones as I write the code. 182 ENEL712-Embedded Systems Design Modular Design Step 4: Data Identification • Embedded software often performs a measure -> calculate -> actuate cycle – Data is normally passed between each of the main steps above • Depending on your application, there might be quite a bit of data (i.e. more than 3 variables) passed between functions – If it is the same 3 variables, then consider grouping your data into more advanced data structures and passing as a pointer – Pointers are normally more efficient as argument data is not copied • Normally, once you start designing the functions for a module, the data required in and out becomes obvious – However you can also plan data structures as part of the architectural design – The data structures can then help you design the functions • A processing flowchart of your application can often uncover the required data transfer – Between each step in the chart, write down the data in and out 183 ENEL712-Embedded Systems Design Modular Design Step 5: Interrupt Identification • When writing software for embedded systems you will often use interrupts – Therefore you need to plan what code goes into the Interrupt Service Routines (ISRs) – and what Interrupts exist! • Deciding what functionality is implemented via interrupts can be challenging – Remember we want as few interrupts as possible • Rules of thumb for choosing interrupt sources: – Use where missing the event (e.g. due to stuck processing in another function) would result in missed or corrupted data – Use where regular timing is required – Don’t use interrupts if they are going to take up all of your processing time • E.g. ADC conversion complete in free-running mode! – Don’t use where polling works fine 184 Modular Design Step 6: Code Reuse Identification ENEL712-Embedded Systems Design • There are two instances where you should consider code reuse: – You are writing a function/driver which is likely to be used in another project – You are about to write a function/driver, which is very similar to that you wrote previously • Remember that in modular software, it is sometimes possible to interchange or reuse modules – This can save a lot of time – but only if you don’t have to modify a lot of code to get it to work • When writing general software modules (e.g. SPI interface or GPS parser), consider writing the module as platform and application independent as possible – Use a low-level function for hardware-specific functionality, and keep the rest independent – Document your code in an application independent way – Use compiler defines to control code paths between different architectures • General code is not typically the most efficient code, therefore performance sacrifices are likely – But then writing in C is much less efficient than assembler… – Use profiling tools to hand-optimize computationally intensive sections if required 185 ENEL712-Embedded Systems Design Lecture References • Embedded Systems 2014 – © Mark Beckerleg & Alan Smith • Microcontroller Systems 2015 – © Mark Beckerleg & Alan Smith 186 Lecture 11 Embedded Software Design D: Advanced C Programming Techniques (4 of 4) ENEL712-Embedded Systems Design “Advanced” C Programming Techniques • At some point you will want to start writing faster, smaller, and more efficient code – Simply knowing for loops and if/else statements only takes you so far… • While improved code structure can make a large difference, so too does the way you write the low-level code – You can only avoid pointers for so long… • Not all ‘advanced techniques’ are hard – you just haven’t been shown them yet – Much of the functionality we will see here is actually simple! • While I use the word advanced here, most of these are not actually advanced topics – “Intermediate-Level C Programming” is a better name – But some content is advanced 188 ENEL712-Embedded Systems Design Switch-Case State Machines • A state-machine (or Finite State-Machine) is a common method for implementing: – – – – Discrete processes with many logical stages Communication interfaces with multiple frames User Interfaces Simple control algorithms • The simplicity comes from its natural implementation as a switch-case statement in C • Best designed using pen and paper, then turned into code switch(state) { case INIT: doINIT(); state = PAUSE; break; case PAUSE: if(doRUN()) state = RUN; break; case RUN: if(doWORK()==0) state = STOP; break; – Or use a computer graphics package • Don’t forget the break statement! – Otherwise you may get ‘case fall-through’ } case STOP: doSTOP(); state = PAUSE; break; 189 ENEL712-Embedded Systems Design Advanced Datatypes • Storing all your data within individual variables leads to longer, more obscure programs – Copying all those variables between function calls can be inefficient too • There are a few advanced datatypes and techniques which can simplify your code and increase efficiency • We are going to look at the four main ones available in C: – – – – Arrays Structures Pointers Function Pointers int buffer[20]; typedef struct { char name; int age; float money; } mydata; char *ptr; char (*fcnptr)(char); 190 ENEL712-Embedded Systems Design Datatypes: Arrays • An array can be used to store a collection of data • Data in an array is stored contiguously (in consecutive memory locations) – This allows pointer arithmetic • All data within an array must be of the same datatype • Arrays can be multi-dimensional – – • The most common error with an array is writing to elements beyond the end of it – • 2D,3D,4D and above Very, very rarely ever beyond 2D! e.g. char x[4]; x[4] = 0; is a big problem! Standard Array Declaration int buffer[20]; Array Datatype Array Name Number of Elements Multi-dimensional Array int matrix[2][2]; Initialized Array int data[2] = {0,1}; The array variable is actually a pointer – It points to the location in memory of the first element in the array 191 ENEL712-Embedded Systems Design Datatypes: Strings • In C (as opposed to most other languages), there is no defined string datatype – Instead, a string is simply an array of characters, terminated with a null (‘\0’) • Depending on the C standard, only ASCII is generally supported – See http://www.asciitable.com/ • There are however many functions available for working with null terminated character arrays (“strings”) – Comparison, copying, concatenating, length – http://www.cplusplus.com/reference/cstring/ • Processing strings is a very common task in many programs – More advanced string datatypes make this job much easier than in C! Remember: if there is no null terminating character in a string, many C functions (printf, strcpy, strlen) will not work and possibly result in an error! Standard String Declaration char my_string[20]; Initialized String char *my_string = “hello”; OR 6 char array! char my_string[] = “hello”; Note the C compiler automatically adds a null (‘\0’) to the end of a string declared in quotes 192 ENEL712-Embedded Systems Design Datatypes: Pointers [1] • Pointers are an efficient method of accessing data without copying it (i.e. in function calls) or indexing it (i.e. traversing an array) • They are however one of the hardest parts of C to get your head around – I didn’t fully understand pointers until my 4th year • To understand pointers, you need to remember how data is stored in memory – Every byte in data memory (RAM) has an individual address (e.g. 0x03F1 – just a hex number) – Pointers exploit this by allowing you to pass the address of where the data is, rather than the data itself See the tutorial video on AUTOnline on pointers http://rypress.com/tutorials/objective-c/c-basics These examples should have brackets… 193 https://bigganjogot.wordpress.com/2011/07/08/pointers-and-arrays-in-c/ ENEL712-Embedded Systems Design Datatypes: Pointers [2] • A pointer example: //Declare a Variable char data = 5; //Create a Pointer char *dptr; data Value In Memory Memory Address (RAM) X X 5 X X 0x51 0x52 0x53 0x54 0x55 Memory addresses are just for example Creates a ‘dangling pointer’ – not pointing to any particular address. Bad practice! //Reference Our Variable dptr = &data; //Dereference Our Pointer char value = *dptr; Take the address of the variable data (i.e. reference it) and store it in our pointer (dptr = 0x53) Return the value at the memory address specified by the pointer (deference it) 194 ENEL712-Embedded Systems Design Datatypes: Pointers [3] • Practical uses of Pointers: – Allow a function to modify the value of an input argument • Effectively make an input argument an output • void myFun(char data_in, char *data_out) – Passing large amounts of data to a function • A pointer allows you to pass just the start of an array or structure, so the function can operate from that starting memory address – Avoids copying all the data within a function call • e.g. char buffer[20]; txData(buffer,20); – Pointer arithmetic • You can perform mathematical functions on pointers – They after all are just memory addresses – integers! • char buffer[20]; buffer++; – In the above, the pointer buffer now points to the second element in the array 195 – A more efficient means of indexing an array (no for loop) ENEL712-Embedded Systems Design Datatypes: Pointers to Functions • As well as creating pointers to variables, you can also create pointers to functions – char (*fcnPtr)(char,char) – The above is a pointer to a function which accepts two chars, and returns a char, called fcnPtr. • Used in a similar way to standard pointers: – fcnPtr = &myFun; //reference an existing function – char value = (*fcnPtr)(2,3); //call the function by dereferencing it • Very useful for functions which call a user implemented function – The user simply supplies a pointer to their function, and the program calls it as if it was part of its own code – Search algorithms, optimization, analysis functions • Quite advanced use, thus seldom used – But invaluable when you need them! Not examined in this course 196 ENEL712-Embedded Systems Design Datatypes: Structures • Structures are a datatype that can collect multiple variables of different types • Each structure has one or more fields, where the structure’s data is stored – Each field has a name like a standard variable – Fields are accessed via a . or ->, depending on whether it is a pointer • • A structure can store any datatype, include other structures and arrays Always pass structures to functions as pointers – This avoids copying the entire structure, and allows you to modify it within the function! Suggested Structure Declaration typedef struct { char name; int age; float money; } mydata; Defining the above Structure mydata John; Accessing Fields of a Structure John.name = ‘c’; John.age = 56; John.money = 35.12; Accessing Fields of a Pointer to a Structure pJohn->name = ‘c’; pJohn->age = 56; pJohn->money = 35.12; See the tutorial video on AUTOnline on structures 197 ENEL712-Embedded Systems Design Standard Library Functions • In this course I recommend you familiarize yourself with the functions available with the “Standard C Library” – Note this library is: • • • The point of the library is provide target optimized versions of commonly required functionality – • Normally the functions are written in assembler, or by highly skilled developers in C (who may also have written the compiler) The Standard C Library is divided amongst a set of header files, many of which you will have already used: – • Compiler dependent (not all compilers support all functions) Changing every decade or so – as new C standards are released (commonly we use C++98, the newer one is C++11) stdlib.h, stdio.h, math.h, string.h We are going to examine some common functions, but the take home message is: – Use the library functions! • They are normally always faster and more reliable than your code! Be careful as many of these functions are non re-entrant – don’t use in interrupts! http://www.cplusplus.com/reference/clibrary/ 198 <stdio.h> ENEL712-Embedded Systems Design Library Functions: printf [Print Formatted] • • • printf allows you to convert one or more variables into a formatted string, and write it to the standard output (stdout) int printf(const char *format, ... ); # of chars written In a Console Application (PC), this will be written to the console On an embedded system, some compilers will automatically print the string out the serial point – Otherwise it disappears! • printf declaration Useful for debugging if you can view the output string Format String Variables to Print Typical Call printf(“Distance: %d [%s]\n”,dis,unit); Format Examples “%d” “%f” “%s” “%c” “%2d” “%4.2f” //print an integer //print a float //print a string (null req!) //print a character //print an integer with 2 digits //print a float with 2 dp & 4 chars http://www.cplusplus.com/reference/cstdio/printf/ Add to Linker Settings for floats in AVR-GCC: -Wl,-u,vfprintf -lprintf_flt -lm 199 <stdio.h> ENEL712-Embedded Systems Design Library Functions: sprintf [String Print Formatted] • sprintf works in a very similar way to printf, except it saves the formatted string into a character array – You can then use this array to send information out the serial port, to an LCD, etc • The array used to store the formatted string in must be able to hold all the formatted characters – Do not let it overrun! – Also allow for a null • For embedded systems, typically more useful than printf Add to Linker Settings for floats in AVR-GCC: -Wl,-u,vfprintf lprintf_flt -lm sprintf declaration int sprintf(char *str, const char *format, ... ); # of chars written Array to Write To Format String Typical Call Variables to Print char str[20]; sprintf(str,“A: %d B: %f”,a,b); Same format strings as printf http://www.cplusplus.com/reference/cstdio/sprintf/ 200 ENEL712-Embedded Systems Design <stdio.h> Library Functions: sscanf [String Scan Formatted] • Rather than writing formatted data, sscanf reads formatted data – Great for reading a string that contains useful data that may be delimited • Works in a very similar way to printf, sprintf, except for each format specifier, an output variable is written to sscanf declaration int sscanf(const char *str, const char *format, ... ); # of variables String to Read read From Format String Output Variables Typical Call char data[] = “1.2,100”; float a; char b; sscanf(data,“%f,%dhh”,a,b); – See scanf documentation for format examples http://www.cplusplus.com/reference/cstdio/sscanf/ • Use a * to indicate to skip data within a string http://www.cplusplus.com/reference/cstdio/scanf/ Add to Linker Settings for floats in AVR-GCC: -Wl,-u,vfprintf -lprintf_flt -lm 201 ENEL712-Embedded Systems Design <stdlib.h> Library Functions: atoi & atof [String to Integer/Float] • For converting single numbers, atoi, atol and atof are quick and easy to use – i = integer – l = long – f = float/double • However they have no error reporting mechanism – They just output 0 if conversion fails • Leading whitespace is ignored Also consider strtof or strtol atoi/atol/atof declarations int atoi(const char *str); long atol(const char *str); float atof(const char *str); Output Number Input String Typical Calls int x = atoi(“100”); float y = atof(“10.52”); Must be Null Terminated! http://www.cplusplus.com/reference/cstdlib/atoi/ http://www.cplusplus.com/reference/cstdlib/atof/ 202 ENEL712-Embedded Systems Design <string.h> Library Functions: memcpy [Memory Copy] • • For copying data between two arrays, memcpy is an efficient routine Specify the destination and source addresses, and the number of bytes to copy – • • • Use sizeof() to calculate the size of any datatype in bytes As the destination and source are specified as void *, any datatype can be copied by this function Remember if you are copying a substring to manually add the null character at the end Ensure your destination buffer always has enough memory! memcpy declaration void *memcpy(void *dest, const void *source, size_t num); Destination Memory Pointer Source Memory Pointer Number of Bytes to Copy Typical Call int data[] = {1,2,3}; int copy[3]; memcpy(copy,data,3*sizeof(int)); Target Specific Function Call String Copying char *str = “hi there bob”; char buffer[20]; memcpy(buffer,&str[3],5*sizeof(int)); buffer[5] = ‘\0’; http://www.cplusplus.com/reference/cstring/memcpy/ 203 ENEL712-Embedded Systems Design <string.h> Library Functions: memset [Memory Set] • For setting an entire array to a specified value, use memset – Efficient way to initialize all the elements in an array • Only works for integer datatypes memset declaration void *memset(void *ptr, int value, size_t num); Memory to Modify Pointer Value to Set Elements to Number of Bytes to Copy Typical Call char data[3]; memset(data,0,3*sizeof(char)); • Normally I use it for initializing numerical arrays to all 0 http://www.cplusplus.com/reference/cstring/memset/ 204 ENEL712-Embedded Systems Design <string.h> Library Functions: strcpy [String Copy] • If you are copying strings (null terminated char arrays), then strcpy is easier to use than memcpy – It automatically works out the number of bytes based on the null character • Note strcpy only works with char arrays terminated with a null character • As always, ensure your destination buffer has enough space! strcpy declaration char *strcpy(char *dest, const char *source); Destination String Pointer Source String Pointer Typical Call char src_str[] = “Hello, World”; char des_str[15]; strcpy(des_str,src_str); http://www.cplusplus.com/reference/cstring/strcpy/ 205 ENEL712-Embedded Systems Design Accessing Variables between Source Files: extern keyword • When you start writing programs with multiple source files, you may find you have a need to share a global variable between source files – While this should be avoided at almost costs, it is possible • To access a variable between source files, it must be defined within one source file, and declared as extern in a header file – Each source file which includes the header file will then have access to that variable • As you know, global variables are ‘bad’, but in embedded systems, they are inevitable – However sharing global variables should be able to be avoided… http://stackoverflow.com/questions/1433204/how-do-i-use-extern-to-sharevariables-between-source-files-in-c CalcSource.c [global definition] int global_var; Assn2.h [header declaration] extern int global_var; Main.c #include “Assn2.h” int main(void) { global_var = 3; } Not examined in this course 206 ENEL712-Embedded Systems Design Static Variables • A very seldom used feature of C is the ability for local variables to keep their value between calls • To do this, you can declare a variable as static • As shown in the example, the variable z keeps its value between function calls • This is typically bad practice, as it makes the function non re-entrant, meaning interrupts and threads cannot use it safely • As an aside, static global variables and functions are variables & functions only accessible within that source file (default anyway) http://stackoverflow.com/questions/572547/what-does-static-mean-in-a-c-program char calc(char x) { static char z = 5; z += x; return z; } printf(“%d\n”,calc(3)); printf(“%d\n”,calc(3)); printf(“%d\n”,calc(3)); >> 8 >> 11 >> 14 Not examined in this course 207 ENEL712-Embedded Systems Design Lecture References • cplusplus .com – – C Library http://www.cplusplus.com/reference/clibrary/ 208 Lecture 12 Embedded Software Design Example ENEL712-Embedded Systems Design Embedded Specifications Example • You are given a specification: – “Design a remote weather station for use in NZ vineyards” • It must be able to be monitor and record temperature, humidity, rainfall, sunlight hours. • It must be self-powered (or minimize battery replacement) • It must communicate wirelessly to the owner’s house • Normally brief, lacking technical detail – A lot of assumptions could be made about the above! • • • • • • Size? MCU? Choice of wireless technology? Distance? Power supply? Sample rate? This Lecture: We will design the software architecture for this problem 210 ENEL712-Embedded Systems Design Hardware Block Diagram MICROCHIP TCN75AVUA. TEMP SENSOR, 2WIRE S, 2.7V ~3.3V regulator Power Supply Battery 7.4V 500mAh Li-Po Clock I2C JTAG STMICROELECTRONICS HTS22 1 HUMIDITY SENSOR, 0 TO 100%, HLGA-6 voltage I 2C ATmega 328P uC Temperature Humidity voltage Hydreon Optical Rain Gauge / Rain Sensor RG-11 Rainfall Pulse Counter SPI EEPROM Maybe? UART voltage Wireless T/R EXCELITAS TECH VT90N1 LDR, 200KOHM, 80MW, VT900 SERIES Sunlight DIGI INTERNATIONAL XBP24Z7SIT-004 ZIGBEE MOD, XBEE PRO ZB, RPSMA CONN 211 ENEL712-Embedded Systems Design Our Task • Design the software architecture for this specification, including: – What source files are required – What functions are required (inc. arguments) – What data structures are required – What peripherals require interrupts – Mathematic algorithms, if required 212 ENEL712-Embedded Systems Design Modularizing Concept Project Specification Module [1] Conceptual Implemented Source File [1A] Function [1A-1] Function [1A-2] Module [2] Source File [1B] Function [1B-1] Source File [2A] Function [2A-1] Function [2A-2] Note this methodology only applies as above to procedural programming (e.g. C) – we will revisit this in Object Orientated 213 Programming ENEL712-Embedded Systems Design Defining Modules • Think of modules as categories of software functionality – Communications Module, Controller Module, UI Module • The task is not to think so much in terms of source code, but in an abstract, high-level grouping of common functionality • It is the first step where you begin to identify the required components from your project specification – 3-5 modules are usually sufficient, depending on the complexity of the project • Think back to our Vineyard Wireless Sensor – What modules would we have? 214 ENEL712-Embedded Systems Design Multiple Source Files • For each module, it can be implemented in software as one or more source files – • Using multiple source files within a project allows you to develop and test individual components in isolation – • – The ability to control access to functions (methods) and variables (data). Unless declared in a header file, variables and functions are only accessible in the local source file. Data and methods to operate on that data are grouped within a common file/object. The easiest solution is to have one source file per module – • It also provides a more defined system architecture Multiple source files also allow a basic form of encapsulation – • In OOP these could be objects However there may be times where more than one source file is more logical An example of the different source files in my Assn 2 solution Take the Sensor Module in our Vineyard sensor, how many source files would we need? 215 ENEL712-Embedded Systems Design Multiple Functions • For each source file, you will have one or more functions – Typically more than one! • Each function performs one small part of the required functionality – E.g. for the assignment, don’t read the whole GPS sentence in one function, but use multiple functions to read each parameter • Adding multiple functions allows you to further divide your software into smaller, easier to write, easier to test and easier to maintain chunks • Keep in mind too many functions is also inefficient An example of the different functions within the gps source filesin my Assn 2 solution – There is no correct number, but 3-6 per source file is fine • Take the Sensor Top-Level Source File in our Vineyard example, what functions would we have? 216 ENEL712-Embedded Systems Design Low Level Mid Level High Level Source Modules Files Modular Structure Sensors sensors.c Communicatio ns comms.c Memory memory.c readAllSensors(data) txMeasmnt(data) txCheckSum(chksum) readyToSend() writeMeasmnt(data) data = readMeasmnt() len = getCapacity() len = freeMemoryLeft() clearMemory() t = readTemp() h = readHum() l = readLight() r = readRain() UART_TxTime(time) UART_TxInt(int) writeByte(addr,byte) byte = readByte(addr) v = readADC(channel) rx = I2CRead(device,addr) I2CWrite(device,addr,tx) UART_Tx(byte) Data structure: Time stamp Temperature Humidity Rainfall Sunshine rx = SPIExchange(tx) Main main.c main() [state machine] ISR(UART_Rx) setup() 217 ENEL712-Embedded Systems Design Lecture References • Embedded Systems 2014 – © Mark Beckerleg & Alan Smith • Microcontroller Systems 2015 – © Mark Beckerleg & Alan Smith 218 Lectures 13 Cost, Memory and Power Estimation ENEL712-Embedded Systems Design Cost Estimation • When designing an embedded product there will often be 3 main areas you will need to forecast/estimate your “costs” (i.e. budget): – Manufacture Costs [how much will it cost to make] • • • • • Component Costs PCB Costs Assembly Costs Testing Costs Distribution Costs – Memory Costs [how much memory do you need] • RAM • Flash • EEPROM – Power/Energy Costs [how much power will it use] • mAh 220 ENEL712-Embedded Systems Design Component Cost and Availability • As already discussed, Cost and Availability should be two important considerations in your design process – We are also going to add in a sustainability consideration • For example, let us say we are designing a power supply that will supply 5V @ 500mA, from an input of 9VDC, for a general purpose device. – We will use Element14 as they are our ‘preferred supplier’ in this example 221 ENEL712-Embedded Systems Design Power Supply Design Example [1] • With the basic specifications entered, we have 71 options – Should we just choose the cheapest? – Or should we choose the one most available? – Or? 222 ENEL712-Embedded Systems Design Cheapest Regulator Option Part of your budgeting should include how many devices you are going to make! - The more devices, the better the price can be! 223 ENEL712-Embedded Systems Design The Effect of Component Costs • A project I did a few years ago was a home automation system – Part of the exercise was to budget raw costs based on functionality and component costs: Don’t forget to check alternate suppliers! Even Digikey NZ vs Digikey UK depending on Exchange Rate Note the large difference between 1 off designs, 224 and building 100, or even 1000! ENEL712-Embedded Systems Design RoHS Compliance • Returning to our Regulator, another important factor in our decision should be RoHS – Restriction of Use of Hazardous Substances – Limits or bans lead, cadmium, mercury and two flame retardants • While not strictly required (in all countries), good practice (and ethics) dictates you should not be involved in polluting the world! – Therefore always choose RoHS compliant components when designing a product – Lead-free solder should also be used – Pollution occurs typically when the device is recycled, or as it commonly happens, ends up in a 3rd world country http://www.rohscompliancedefinition.com/ http://en.wikipedia.org/wiki/Restriction_of_Hazardous_Substances_Directive 225 ENEL712-Embedded Systems Design PCB Manufacture • When it comes to getting your PCB manufactured, you have LOTS of options! – Local • • • • Circuit Labs [http://www.circuitlabs.co.nz/] PCB Zone [http://www.pcbzone.net/] Capital Circuits [http://www.capitalcircuits.co.nz/] QualiEco Circuits [http://www.qualiecocircuits.co.nz/] – Overseas • Lots of manufacturers in China – Just be careful, quality is often an issue – The cheapest PCB manufacturer is definitely to be avoided! • “You get what you pay for” • Most companies operate on a per-quote basis – Typically you supply your PCB files as well as specifications (PCB material, special requirements) – Prices vary based on area, number of layers, tolerances, smallest features, number of PCBs, etc 226 ENEL712-Embedded Systems Design PCB Assembly • In addition to PCB manufacture, you can pay someone to assemble your PCB for you – Triode [www.triode.co.nz] • Many companies offer PCB manufacture, assembly, programming and testing as a single service – Send them your design, parts-list, compiler files and test specifications, and returned should be working PCBs! • Obviously if your design is wrong, then they won’t fix it for you – Many have experienced problems doing this in China, from poor assembly, to copies of their products appearing for sale on Alibaba… – As with manufacture, you get what you pay for This is not applicable to student projects – you must assemble your projects yourself! 227 ENEL712-Embedded Systems Design Estimating Memory Usage • As we saw when selecting an MCU, one of the main options your have is the amount of memory – e.g. mega8, mega16, mega32, mega64, mega128… • There are three main types of memory you need to budget for: – Program Memory [typically Flash] – Data Memory [typically RAM] – Non-Volatile Memory [typically EEPROM] • Budgeting the last two is usually much easier – But we will look at all three 228 ENEL712-Embedded Systems Design C Programs in MCU Memory [1] • Before we can begin, we need to look at how programs in C are stored in MCU memory Interrupt stuff… This is our entire program! Only a while(1) inside our main function still uses 176 bytes of program memory (debug build). - The compiler still adds initialization code + interrupt vectors Note the .text section is the program memory 229 ENEL712-Embedded Systems Design C Programs in MCU Memory [2] • Let’s send the numbers 0->255 repeatedly out the serial port (ignoring setup) General Purpose Registers We added a local variable (data), but no data memory is used? Remember our General Purpose Registers? They act as data memory too! - Only for very small programs 230 ENEL712-Embedded Systems Design C Programs in MCU Memory [3] • Let’s make the data variable a global variable With a global variable, and optimization disabled, the compiler treats the data variable as data memory. Data Memory Access (starts at 0x0100) 231 ENEL712-Embedded Systems Design C Programs in MCU Memory [4] • Let’s initialize our global variable to a nonzero value Hold on – why do we now have 2 bytes in data memory? We still only have one char? Same program as before What does this instruction do? 232 ENEL712-Embedded Systems Design • • Initialized Global Memory Considerations If we define a global variable (which sits in RAM) to a constant, then if power is removed, how does this variable retain(?) this constant value? Obviously, we must be using some sort of non-volatile memory – In reality we actually use the Program Memory to store the variable value! • Part of the initialization of the microcontroller involves copying from Flash all initialized global variables, before your program starts running SRAM Unint Vars Init Vars 0x0100 0x10FF Stack Remember RAM has sections for both initialized and uninitialized global variables elpm reads from Program Constant Memory 233 ENEL712-Embedded Systems Design Quick Summary of Compilers & Memory So Far • What we have established so far: – Local variables may be replaced by general purpose registers – Global variables (uninitialized, or = 0) are placed in data memory, and take the same amount of memory as the data type – Global variables which are initialized require memory in both Flash and RAM – Even small programs require a number of instructions • When estimating memory requirements: – To be on the safe side, assume all variables require data memory (RAM), and all initialized (!=0) variables require double the memory 234 ENEL712-Embedded Systems Design Memory Estimation Example [1] • A product is to be designed to receive NMEA GPS information over a UART – It is to double buffer the received NMEA information • One buffer for receiving the raw characters • One buffer for processing a complete NMEA sentence – Each NMEA string is assumed to be <= 100 characters • How much memory will our double-buffered NMEA program require (in bytes)? • Solution: – Assume ISR buffer is global memory, processing buffer is local, both uninitialized – Each character is 1 byte • (You need to know how many bytes each datatype requires!) – 2 buffers x 100 elements each x 1 byte per character = 200 bytes • (As both buffers are uninitialized, no double up in Flash) How much RAM do we have in our AT90USB1287? 235 ENEL712-Embedded Systems Design Memory Estimation Example [2] • Following our Vineyard Weather Station Example: – 1 measurement per second of the following data • • • • • • Time [32 bit] Temperature [10 bit] Humidity [10 bit] Rainfall [8 bit] Sunlight [8 bit] Questions: – If we were to buffer the above data for 12 hours, how much memory would we need? • Solution: 68bits per measurement (32 + 20 + 16), requires 72 bits to store in memory without compression (9 bytes). 43,200 seconds in 12 hours, therefore memory required is 43,200 * 9 = 388.8KB. • Follow up question – how could we store this in our MCU/weather station? – If we can transmit data at 250kbps, how long would it take to transmit 12 hours of data (assuming all bits are data bits)? • Solution: 250kbps = 31.25kBps. 388.8/31.25 = 12.44 seconds. • Follow up question – if every measurement was transmitted with a 16bit checksum, how long would it take to send all the data? 236 ENEL712-Embedded Systems Design Recursion Example • What’s wrong with this program? • Does it really have 0 bytes data memory usage? • Recursion is a fantastic way to run out of room on the stack! – Every call of myfunc() places the current value of x on the stack – Yes the program could technically exit, but we would run out of room much earlier than that! • Summary: Data memory usage can only detect actual variables declared, it will not pick up recursion or dynamic memory Avoid recursion as much as possible, as shown here, it can cause all sorts of problems 237 ENEL712-Embedded Systems Design Program Memory Estimation • Following our Vineyard Weather Station Example: – How much program memory would we require? • That is actually a really hard question to answer! – It is highly dependent on: • • • • • • • • How you write the program How efficient your code is The language you write it in How good the compiler is at size optimization (if a compiler is used) What compiler settings are used What libraries are used Use of floating point numbers In reality, I do not know an easy way to estimate the program memory usage, but techniques I have used include: – Use previous projects as benchmarks – If you have a lot of constants, these can be tallied – Write the program and see! • Buy an evaluation kit with a MCU with lots of memory, prototype your program, then have a look how much memory you are using 238 ENEL712-Embedded Systems Design Estimating Power Usage • When you are designing an embedded device it is quite likely that, eventually, one of your designs will be battery powered • When prototyping, bench-top power supplies are ‘free power’ – But once deployed to the field, how do you know how long your device will last? – Imagine a smart phone that only lasted 1 hour… – Or a data logger on a kiwi that lasted 1 day… • Power specifications can be of the form: – It must last 1 year with a standard battery – Or, It must have a minimum service time of 6 months • Designing power efficient embedded systems can be a real challenge and it will test your knowledge of electronics and microcontrollers! 239 ENEL712-Embedded Systems Design Power Estimation Example [1] • An LED is connected in the following circuit: Constant Load! 27Ω 1/4W Resistor 3.7V 750mAh LiPo 2.5V LDO Vreg 5mm RED LED Vf = 2.1V Irated = 15mA • How long will the battery last before it is completely discharged? ILED = (2.5-2.1)/27 = 14.8mA, PVReg = (3.7-2.5)*14.8m = 17.8mW, PLED = (2.5-2.1)*14.8m = 31.1mW, PRes = 14.8m^2 * 27 = 5.9mW EBat = 2.775Wh, Time = EBat / (PVReg + PLED + PRes) = 50.63hrs, OR 750mAh/14.8m = 50.63hrs 240 ENEL712-Embedded Systems Design A Note on Discharge Curves • Have a look for the discharge curves for any battery you are working with, the Ah rating is only an indication! – Depending on the current output (C), different ratings will be achieved – Also depends on the age of the battery, and the number of charge/discharge cycles – Also watch out for over discharging the battery, this will cause permanent damage 3.7V 2400mAh Lithium-Polymer Battery Damage! 241 ENEL712-Embedded Systems Design Wireless Communications Power Estimation • Estimating the power requirements for devices with a constant load is easy • Estimating power for timevarying loads is much more complicated • A typical example is a wireless communications interface: – Lots of current when it’s Tx – Small current when Rx/Idle – Almost none when asleep • How would you estimate the power required? 242 ENEL712-Embedded Systems Design Wireless Power Estimation [1] • Rough Method: – Create a schedule of likely operating modes over a typical time period Operating Time Per Hour Current Required 15secs / 12 hours 1.25s 250mA RX/IDLE 600secs / 12 hours 50s 55mA ASLEEP Remainder 3548.75s 10µA TX Order not important! Integrate to find total capacity required: (1.25*250 + 50*55 + 3548.75*10e-3)/3600 = 0.8606 mAh For 12 hours, require 10.323 mAh. An 8000mAh battery should easily last a year. 243 ENEL712-Embedded Systems Design Wireless Power Estimation [2] • Accurate method: – Build it and measure the current! Measure the current consumption by logging the voltage drop across a small, precision resistor Numerically integrate this area to get mAh (e.g. trapezoidal) The same method can be applied to any other time-varying load, including MCUs! 244 ENEL712-Embedded Systems Design Microcontroller Power Estimation [1] • Estimating the current consumption of an MCU is quite a complex task. Roughly, you can just use the datasheet together with Vcc and Freq: Increasing Frequency Increasing Voltage Low Current = Slow MCU & Low Voltage! 245 ENEL712-Embedded Systems Design Microcontroller Power Estimation [2] Similar to the process we used for the wireless communication s! Don’t be afraid to integrate if you can… http://dkc1.digikey.com/nz/en/tod/Atmel/PicoPower_NoAudio/PicoPower_NoAudio.html 246 ENEL712-Embedded Systems Design Microcontroller Power Estimation [3] • Some Manufacturers provide software tools for estimating the power consumption of their processors: • Typically however, these tools only exist for advanced processors and ASIC/FPGA designers 247 ENEL712-Embedded Systems Design Power Saving Modes • Most MCUs provide a number of “sleep modes” that enable the application to shut down unused modules in the MCU, thereby saving substantial power Remember in digital devices, clocking (changing state) requires power! 248 ENEL712-Embedded Systems Design Enabling Power Saving Modes • Sleep Mode Control Register: 249 ENEL712-Embedded Systems Design Other Way to Save Power in an MCU • Use the Power Reduction Register: • Follow the Datasheet Recommendations 250 ENEL712-Embedded Systems Design Lecture References • AT90USB1287 Datasheet – • © Atmel Digi-Key picoPower Presentation – – © Atmel & Digi-Key http://dkc1.digikey.com/nz/en/tod/Atmel/PicoPower_NoAudio/PicoPower_NoAudio.h tml 251 Part II: Object Orientated Programming (WK 7-12) Lecture 14 Introduction to OOP ENEL712-Embedded Systems Design What is Object Orientated Programming? • “Object-Orientated Programming (OOP) is a programming language model organized around objects, rather than actions, and around data, rather than logic” • Features: – – – – It is a modular approach It allows reusability Promotes information hiding (encapsulation) Typically organised as a hierarchy • We will be using C# as the language to teach you OOP – There are many other OOP languages: • C++, Java, MATLAB, Python, PHP, etc http://searchsoa.techtarget.com/definition/object-oriented-programming 254 ENEL712-Embedded Systems Design Now, What is C#? • C# is a modern (15 years old) programming language intended to be simple, general-purpose and object orientated. • FORTRAN (1957), C (1972), C++ (1983), C# (2001) • Built on .NET (Microsoft Software Framework) • Developed by Microsoft – Originally PC based, now seeing use on Linux and MAC 255 ENEL712-Embedded Systems Design What can you do with C#? • Develop: – Quickly build Graphical User Interface (GUI) programs for Windows – Dynamic websites (based on ASP.NET) – Interactive Microsoft Silverlight programs – Microsoft Office add-ins – Code libraries for redistributing proprietary code – Windows Azure Cloud based computing applications 256 ENEL712-Embedded Systems Design C++, C# + Excel = JSteam Interactive Office Ribbon Custom Excel Functions Graphical Modelling 257 ENEL712-Embedded Systems Design Why use C#? • By design, C# is the programming language that most directly implements the Common Language Infrastructure (CLI) – This is designed to make programming easier! – CLI (and CLR - .NET) implement a range of libraries to make developing applications faster and easier • C# versus C++ – Simpler language, more powerful integrations into Office, Web and Cloud computing, and faster application development. • C# versus C – Managed code (automatic garbage collection, platform independent code), object orientated programming, more powerful supplied libraries. 258 ENEL712-Embedded Systems Design What will You Learn in EDS – OOP? • Effective C# usage – Syntax – Application Development – .NET Programming • Object Orientated Programming – Object / Class based design 259 ENEL712-Embedded Systems Design Programming with C# • Programming is a TRANSFERABLE SKILL – Concepts you learned in C++ are common in C# – Syntax may change, but usually similar! – However this course will introduce Object-Orientated Programming (OOP) • C# is compiled to an intermediate language – This means it compiles to machine code when you run it • C# can be linked to other software – C / C++, .NET, Java, FORTRAN, MATLAB 260 ENEL712-Embedded Systems Design Why Not Use C#? • C# is not designed for high speed performance (e.g. numerical computations, compression, encoding) – This is because C# does not compile directly to machine code until you run it – For performance code consider C, native C++ or FORTRAN • C# is primarily a Microsoft Windows language, therefore programs cannot be easily ported to Mac / Linux – However as of November 2014, .NET is open source and as of April 2015, Visual Studio is multi-os compatible – Very interesting development... Worth watching! 261 ENEL712-Embedded Systems Design C# Resources • Useful Reading on AUTOnline – I will also post videos as we cover content • Lots and lots and lots of videos on YouTube! – Plus lots of good websites • Get Microsoft Visual 2013 Free for free to use at home: – https://www.visualstudio.com/enus/products/free-developer-offers-vs.aspx • Keep an eye out for Visual Studio 2015 soon! 262 Lecture 15 OOP-Part A ENEL712-Embedded Systems Design Object Orientated Programming (OOP) • OOP is a way of programming such that you create objects (classes) as modular pieces of your code – Each object contains its own data fields (properties or data members) and functions (methods) • Each object represents a module of your program – For example if you are writing finance software an object might represent a bank account – Each bank account has properties (balance, overdraft) as well as methods (open, close, suspend) • OOP is designed to make programming easier – Once programs become large they often become difficult to manage – OOP allows the programmer to design individual objects which can be individually programmed, debugged and verified 264 ENEL712-Embedded Systems Design OOP Terminology: Class • A class contains both data and methods to manipulate that data – It is a template for creating an object (not to be confused with the C# data type ‘object’) • The Class code and its data are integrated into one object – This is called encapsulation • Private data can only be modified by class code – This increases code reliability and simplifies data management 265 ENEL712-Embedded Systems Design OOP Terminology: Object • An object is a specific instance of a class – It is created using the new keyword • Each object created from a class has the same properties and methods – However each object has its own copy of data • Using our bank account example, each object therefore has the same properties (balance) and methods (open, close) – But the values stored in balance, overdraft are unique to each object 266 ENEL712-Embedded Systems Design OOP Terminology: Properties • The Properties of a class contain the object data – Bank account balance – Filestream to an opened file – Length of an array • Also known as data fields or data members • Properties of an object are accessed using a dot ‘.’ – array.Length – account.Balance • However it is good practice to only allow access to properties which require user access – – private int Balance //not accessible from outside the class public int Balance //accessible from outside the class 267 ENEL712-Embedded Systems Design OOP Terminology: Methods • The Methods of a class are the functions the object can perform – Open a bank account – Open a wave file – Copy an array • As with properties, methods are accessed using a dot – array.Copy() – account.Open() • Methods are also declared as private or public – Only public methods are available outside the class 268 ENEL712-Embedded Systems Design OOP Terminology: Encapsulation • The concept of a class is based on that of encapsulation – As a user of a class we are not too concerned with how the class does what we ask it to (e.g. open a file) or where it maintains internal data – We just want it to work! • Encapsulation has two purposes – To combine methods and properties inside a class – To control accessibility of the methods and data (private and public) • A class is an example of encapsulation 269 ENEL712-Embedded Systems Design Defining a Class • Classes are created in C# using the class keyword – Remember classes should be defined within a namespace! class Circle { public int radius; public double Area() { return Math.PI * radius * radius; } } 270 ENEL712-Embedded Systems Design Allocating Memory for a Class • A class is a reference type (as opposed to a value type such as an int) – This means when you define a class variable it only creates an empty reference • e.g. Circle c; • Memory is only allocated for the class and all its properties once the new keyword has been called – The class variable (c) exists on the stack – All properties exist on the heap 271 ENEL712-Embedded Systems Design Using the Circle Class • An object of class Circle is created using the new keyword Circle c; c = new Circle(); double a = c.Area(); //Create a circle variable //Initialize it //what will a be? c.radius = 4; double a2 = c.Area(); //and what will a2 be? • In fact the above is bad practice. You should not be able to change the radius property of the object from outside the class – This is not utilizing encapsulation (2), controlling accessibility – So how can we set it? 272 ENEL712-Embedded Systems Design Circle Class with better Encapsulation • Below is the circle class rewritten with the radius property now declared as private – This means it cannot be set or read from outside the class – By default all properties and methods are private – Can you see a problem with the below class? class Circle { private int radius; //better encapsulation public double Area() { return Math.PI * radius * radius; } } 273 ENEL712-Embedded Systems Design Working with Constructors • When you use the new keyword to create an object the runtime has to construct the object using your class definition – This requires the runtime to allocate memory for the object and its fields, then invoke a constructor to perform any initialization – If you do not define a constructor the compiler will automatically generate one for you • The constructor is a special method that runs automatically when you create an instance of a class – It has the same name as the class – It can take parameters, but it cannot return anything (not even void) – It is used to initialize the properties of the object being created 274 ENEL712-Embedded Systems Design Circle Class with a Constructor • The constructor below performs the same job as the compiler generated default constructor – Has it fixed our problem with this class? class Circle { private int radius; public Circle() //default constructor { radius = 0; } public double Area() { return Math.PI * radius * radius; } } 275 ENEL712-Embedded Systems Design Overloading Constructors • Another important concept of OOP is the ability to overload a method – This means you can have multiple methods called the same name, but each accepting different parameter types, and or numbers of parameters class Circle { private int radius; public Circle() //default constructor { radius = 0; } public Circle(int r) //overloaded constructor { radius = r; //assign user specified radius } public double Area() { return Math.PI * radius * radius; } } 276 ENEL712-Embedded Systems Design Using the New Circle Class • With the new circle class as in the previous slide, we can now use it like so: Circle c; c = new Circle(4); //Create a circle variable //Initialize it (radius = 4) double a = c.Area(); //pi*4*4 //We can also create as follows: Circle c2 = new Circle(3); double a2 = c2.Area(); //pi*3*3 277 ENEL712-Embedded Systems Design get and set Methods • As well as initializing the property radius via a constructor, the class can also be written to include get and set methods – These allow indirect access to a private property – They also allow you to modify how the value is returned (i.e. change from internal to SI units) 278 ENEL712-Embedded Systems Design Circle Class with get and set class Circle { private int _radius; public int radius { get { //private internal property //public user accessible property return _radius; //return private property _radius _radius = value; //note implicit parameter value } set { } } public Circle(int r) { _radius = r; } //overloaded constructor //assign user specified radius public double Area() { return Math.PI * _radius * _radius; } } 279 Lecture 16 OOP-Part B ENEL712-Embedded Systems Design Static Methods • Sometimes you will find that not all methods belong naturally to an instance of a class – Typically they are utility methods, that is they are used independent of any particular class instance – Examples are the System.Math methods: Math m = new Math(); double d = m.Sqrt(16); //create a new Math object //now call sqrt (wrong) • In the above example the Sqrt function does not require any internal properties of the Math class to run – It only requires information from the argument list – Therefore in order to group similar functions, in this case they are created as static methods of the Math class 281 ENEL712-Embedded Systems Design Creating a Static Method • Below is an example of how the Sqrt function of the Math Class could be implemented: class Math { public static double Sqrt(double d) { … //sqrt code } … //other methods } 282 ENEL712-Embedded Systems Design Static Method Considerations • If a method is declared as static: – It can only call other static methods of the class – It can only access static properties of the class • However: – Non-static methods can call static methods using the standard calling convention: • Class.Static_Method( ) 283 ENEL712-Embedded Systems Design Static Data Members • You can also create static data members (properties) of a class – A static data member is a shared field, it is common to all instances of a class – This is opposed to non-static data members which are local to each instance (typical OOP paradigm) • One use is to keep track of how many instances of a class have been created – Similar to how .NET knows when to free unused memory 284 ENEL712-Embedded Systems Design Circle Class Revisited class Circle { private int radius; public static int numCircles = 0; //we can initialize static data members public Circle() { radius = 0; numCircles++; } //default constructor public Circle(int r) { radius = r; numCircles++; } //overloaded constructor //increment the number of circle instances //assign user specified radius //increment public double Area() { return Math.PI * radius * radius; } } 285 ENEL712-Embedded Systems Design Static Data Member via const • By prefixing a data member with the const keyword you can declare a static field which never changes value – An example is the PI data member of the Math Class: class Math { … public const double PI = 3.14159265358979323846; } 286 ENEL712-Embedded Systems Design Inheritance • Inheritance is a key concept in OOP. You use inheritance to avoid repetition when defining different classes that share a number of features in common. – For example if you were creating objects to represent the various employees in an office – A base class could be a employee class, with properties such as IRD number and Pay Rate – A derived class could be a manager, cleaner, apprentice, etc, each with their own methods (responsibilities) • This approach allows a common set of properties and methods in the employee class that all managers, cleaners, etc can use. – But it also allows a customization based on the employee type 287 ENEL712-Embedded Systems Design Base Class vs Derived Class • You can declare a class that inherits from another class using: class DerivedClass : BaseClass { … //your code here } • This allows the derived class to access the properties and methods of BaseClass – Note you cannot derive from two classes! • A common example is when creating a Windows Forms Application: – Your Windows Forms Application Class (Form1) inherits from the base class Windows.Forms.Form – Note the keyword partial just means the class definition is in multiple files public partial class Form1 : Form { public Form1() { … //constructor code } … //your event handlers and methods } 288 ENEL712-Embedded Systems Design Calling Base Class Constructors • As the derived class inherits all properties of the base class, typically the base class constructor must also be called in order to initialize these properties – This is done using the base keyword and is good practice! class Employee //base class { public Employee(string name) { .. } } //constructor class Manager : Employee //derived class { public Manager(string name) : base(name) //calls Employee(name) { .. } } 289 ENEL712-Embedded Systems Design Function Overloading • Function overloading provides a means to provide one method name, but multiple implementations of the method based on: – The data type of the arguments supplied – The number of arguments supplied • We have already seen this in our Circle class constructor • It is also fundamental to the Math Class – Math.Sqrt(double d) – Math.Sqrt(float f) 290 ENEL712-Embedded Systems Design Function Overloading in System.Math • Below is an example of how function overloading could be used in the System.Math Class class Math { public static double Sqrt(double d) { … //sqrt code for double precision } public static float Sqrt(float f) { … //sqrt code for single precision } … //other methods } 291 ENEL712-Embedded Systems Design Operator Overloading • Using OOP it is possible to overload the existing operators (+ - * / etc) to allow them to function with your class – This is how ‘+’ is used to concatenate in the string class • However there are some constraints: – You cannot change the precedence of an operator – You cannot invent new operators – You cannot change the meaning of operators with existing data types 292 ENEL712-Embedded Systems Design Operator Overloading Example class Hour //class for representing an hour { private int value; //numerical value of the hour public Hour(int initialValue) //constructor { this.value = initialValue; //‘this’ represents this object } public static Hour operator +(Hour lhs, Hour rhs) { //Adding hour objects together returns a new hour object //with the value properties added return new Hour(lhs.value + rhs.value); } … } • • Note that the operator method is both public and static You must also make sure to provide the correct number of arguments – Unary operators (+, -) only have one! 293 ENEL712-Embedded Systems Design Enumerations • Enumerations allow you to assign meaningful names to values such as 0, 1, 2, etc. – Note this is not an OOP concept – Useful in switch-case statements for processing alternatives enum State {On, Off}; //values 0 and 1 enum Season {Spring, Summer, Autumn, Winter}; //values 0 - 3 • To read an enumeration, assign it to an enumeration variable: Season colourful = Season.Autumn; Console.WriteLine(colourful); //writes “Autumn” Console.WriteLine((int)colourful); //writes “2” 294 ENEL712-Embedded Systems Design Programming Exercise 295 Lecture 17 OOP-Part C ENEL712-Embedded Systems Design Virtual Methods • When designing an OO solution sometimes you will design methods as placeholders for derived classes to provide their own implementation – However if the derived class does not provide its own implementation, the placeholder method can be used instead • This concept is known as a virtual method – I.e. a method that is designed to be overridden in the derived class – It is however optional for it to be overridden • The best example of this is the ToString method – Every class has a ToString method inherited from the System.Object class – You can choose to override it, or you can use the default one 297 ENEL712-Embedded Systems Design Virtual Method Example • The ToString method in the System.Object class is defined like this: namespace System { class Object { public virtual string ToString() { … } … } … } • • Every class that now inherits from System.Object will now also inherit the ToString method, however how useful it is will depend on whether the derived class overrides it with something more useful! By default it will return just the class name 298 ENEL712-Embedded Systems Design Overriding Virtual Methods • If a base class declares that a method is virtual, a derived class can use the override keyword to declare another implementation of that method class Circle { public override string ToString() { … //your code here } } • Note the use of the override keyword! 299 ENEL712-Embedded Systems Design Virtual Method Rules • There are a few rules around using virtual methods: – A virtual method cannot be private – The signatures (declarations) of the virtual and override methods must be the same – You can only override virtual methods – If you do not use the override keyword, you will ‘hide’ the virtual method and get a compiler warning – do not do this! 300 ENEL712-Embedded Systems Design Polymorphism • Virtual methods make it possible to call different versions of the same method, based on the type of the object determined dynamically at run time • The concept of the same method (e.g. ToString) invoking a different version depending on its context (which class it belongs to) is called polymorphism • Polymorphism literally means ‘many forms’ • Note this is not function overloading 301 ENEL712-Embedded Systems Design Protected Access • So far we have seen the keywords public and private, and viewed them in isolation to a single class – public – accessible to everyone – private – accessible to only the class itself • Consider now you are designing a class which will be inherited by other classes – In addition, you want derived classes to be able to access one or more data members or methods – The solution is to declare the data members or methods as protected • A protected data member or method is accessible only to the class itself and derived classes – Or - Not accessible outside the class, unless in a derived class 302 ENEL712-Embedded Systems Design Protected Data Member Example • Simple example of a protected data member: class Circle { protected double radius; //protected member … } class BottleCap : Circle { public double area() { return Math.Pi * radius * radius; //access here } … } 303 ENEL712-Embedded Systems Design Abstract Methods • An abstract method is very similar to a virtual method, and follows most of the same rules – I.e. designed to be overridden, same declaration, cannot be private • The exception is an abstract method must be overridden, it is no longer optional • An abstract method is used if it does not make sense to provide a default implementation in the base class, but all derived classes must declare their own implementations – Therefore the abstract method is always empty! • In addition, abstract methods may only be declared in abstract classes 304 ENEL712-Embedded Systems Design Abstract Method Example • As stated, abstract methods may only be declared in abstract classes: abstract class Shape //note abstract class definition { abstract void area(); //Override depending on shape! … } class Circle : Shape { public override double area() { return Math.Pi * radius * radius; } … } 305 ENEL712-Embedded Systems Design Sealed Classes & Methods • If you are writing a class that you do not want to be inherited from, you can declare it as a sealed class – This prevents any further class from inheriting from your class – A rather extreme form of encapsulation • A little unusual to do (I personally never have done this) • Alternatively, you can also declare an override method, in an unsealed class, as a sealed method – This means a derived class cannot override this method – Effectively the last implementation of the method, no further derived classes can customize it – Also an unusual thing to do 306 ENEL712-Embedded Systems Design Object Orientated Summary • Things to remember: – Classes, objects, properties, methods, constructors, overloading, encapsulation, inheritance, polymorphism, private, public, protected, virtual, abstract, sealed • You will be expected to write a C# class definition (or more than one) in the exam – So practice declaring them, as per the programming exercise and previous exam questions • You will also be expected to know how to use an existing class, from the provided definition 307 Lecture 18 Introduction to .NET ENEL712-Embedded Systems Design What is .NET? • .NET is a software framework developed by Microsoft – Latest version is .NET 4.8.0 in May 2021 – Free download for any Windows PC* • Primary objectives: – Provide a consistent object-orientated programming environment – Provide a code-execution environment that minimizes software deployment – A consistent developer experience across Windows and Web based applications – Built on industry standards to maintain security, performance and integration. 309 ENEL712-Embedded Systems Design Recent Changes to .NET https://github.com/dotnet/roslyn The .NET Compiler Platform ("Roslyn") provides opensource C# and Visual Basic compilers with rich code analysis APIs. http://www.drdobbs.com/windows/c-and-nets-sudden-ubiquity/240169282 http://techcrunch.com/2014/11/12/microsoft-takes-net-open-source-and-cross-platform/ 310 ENEL712-Embedded Systems Design .NET Components • Common Language Runtime (CLR) – The foundation of the .NET Framework. – Provides the code-execution environment • Common Type System (CTS) – Facilitates common data types (such as int) between .NET languages • .NET Class Library – Comprehensive library of object-orientated types you can use to develop your application 311 ENEL712-Embedded Systems Design .NET Framework in Context 3rd Party Code Your C# Application Native C / C++ Applications Class Library .NET Your PC CLR http://msdn.microsoft.com/en-us/library/zw4w595w.aspx 312 ENEL712-Embedded Systems Design Common Language Runtime • The CLR is responsible for: – – – – – – Memory management Thread execution Code execution Code Safety Verification Compilation Security • Fundamentally: – Makes program easier to write, debug, and deploy 313 ENEL712-Embedded Systems Design CLR: An Implementation of CLI • Common Language Infrastructure (CLI) • • Developed by Microsoft, but an open specification Allows for Mono (Linux), an open source version of .NET • Defines an environment that allows multiple high-level languages to be used without being compiled for specific architectures http://en.wikipedia.org/wiki/File:Overview_of_the_Common_Language_Infrastructure.svg 314 ENEL712-Embedded Systems Design How does CLR work? • An application of Just-In-Time (JIT) compilation – This means machine code is not produced until the code actually runs – This allows the CLR to compile the code for the architecture it is running on • C# / VB.NET code is ‘compiled’ – but not to machine code – Under CLR it is compiled to Mircosoft Intermediate Language(MSIL) [now called CIL – Common Intermediate Language] – The MSIL version of your application is then compiled to machine code ‘just-in-time’ when you execute it 315 ENEL712-Embedded Systems Design Advantages of the CLR • Memory management – The CLR takes care of all dynamic memory for you, virtually eliminating memory leaks and invalid memory references • Mix High Level Languages – A developer can code in multiple languages, but it all compiles to the same MSIL description • Accelerate Developer Productivity – Focus less on memory management and more on real application development. Leverage the Class Library to use powerful low-level types like strings and arrays. 316 ENEL712-Embedded Systems Design Disadvantages of the CLR • Due to the extra compilation step managed code is not as fast as unmanaged (native) code – For performance algorithms it is best to use C / native C++ and create a static (.lib) or Dynamically Linked Library (.dll). • Interfacing to legacy (native) code can be confusing – Marshalling, Interoperability Keywords, Unsafe Code 317 ENEL712-Embedded Systems Design CLR: Dynamic Memory Example C++ Pointers (tricky) int *x = new int[5]; x[5] = 10; Array overwrite: crash, or blue screen of death! delete [] x; memory: delete x; Free Manual otherwise memory leak! C# Array int[] x = new int[5]; x[5] = 10; Array overwrite: Runtime error Free memory: CLR manages memory release via “Garbage Collection” More in .NET Memory Management Lecture 318 ENEL712-Embedded Systems Design .NET Class Library • To make development even easier, .NET provides a suite of classes, interfaces and value types you can use – All .NET Framework types are Common Language Specification (CLS) compliant, meaning they can be used from many programming languages • Commonly used components include: – – – – – File I/O objects String management objects Data collection objects Database objects Windows GUI objects 319 ENEL712-Embedded Systems Design .NET Data Types Category Class Name Description C++ Data Type Integer Byte (or byte) 8 bit unsigned integer char Int16 16 bit signed integer short Int32 (or int) 32 bit signed integer int Int64 64 bit signed integer __int64 Single Single Precision real float Double Double Precision real double Logical Bool Boolean Value bool Other Char A unicode 16 bit character wchar_t IntPtr A signed integer - Object Root of the object hierarchy Object* String A string of unicode characters String* Floating Point 320 ENEL712-Embedded Systems Design Other Useful Types System.IO.Stream - A generic class of a sequence of bytes System.IO.FileStream - For reading and writing files System.IO.BinaryReader - For reading a stream as sequence of binary values 321 ENEL712-Embedded Systems Design Namespaces • With the thousands of classes provided by .NET it can be difficult to come up with new class names! – The old method was to add an underscore in front of user objects, e.g. _FileIO. • However a namespace allows you to group common classes into a ‘container’ – A namespace acts like a folder on your computer, keeping classes (or folders) organised – It also allows you to only use the classes you want, reducing the risk of a name overlap. 322 ENEL712-Embedded Systems Design Namespaces (continued) • In the previous slide, we had: System.IO.Stream • Where System is the base namespace, IO is the Input / Output namespace, and Stream is the class definition we want – We use a dot to drill down through the namespace hierarchy • Using this naming strategy, we could have another class called ‘Stream’ in another namespace, and they would not conflict* *Provided you are not using both namespaces 323 ENEL712-Embedded Systems Design Using Namespaces • Writing the entire namespace list can be tedious: System.IO.Stream mySteam; • So we can use the ‘using’ keyword to include the namespace in the current file: using System.IO; //top of the file Stream myStream; 324 ENEL712-Embedded Systems Design System Namespace • The System namespace is the root namespace for all C# classes, interfaces and types – This includes our base data types, byte, int, etc. – Common sub-namespaces include: Namespace Description System.IO Input and output to files / streams System.Collections Lists / dictionaries System.Drawing Basic drawing types System.Runtime CLR interaction and interoperability services System.Windows.Forms Classes for Windows based applications System.Web Classes for browser / server communication 325 ENEL712-Embedded Systems Design Custom Namespaces • You can easily add your own namespaces – In fact it is preferred – It is bad practice to fill up the ‘global namespace’ with user classes. • For example: namespace AUT { //Classes class AUTClass { … } } Then in your application: using AUT; 326 ENEL712-Embedded Systems Design Recent Changes to Visual Studio • • As of April 29 2015 Visual Studio is now available in a reduced form as “Visual Studio Code” for multiple operating systems “Only a few years ago, today’s announcement would have come as a shock. Now, it’s more of a nice surprise.” https://code.visualstudio.com/Download http://techcrunch.com/2015/04/29/microsoft-shocks-the-world-with-visualstudio-code-a-free-code-editor-for-os-x-linux-and-windows/#.yt64l4:LEOC 327 ENEL712-Embedded Systems Design Automatic Memory Management • Automatic memory management is one of the services that the Common Language Runtime provides during Managed Execution • The CLR’s Garbage Collection (GC) manages the allocation and release of memory for an application • For developers this means you do not have to write code to perform memory management tasks – This eliminates common problems such as forgetting to free an object, or attempting to access an object that has already been freed 328 ENEL712-Embedded Systems Design Allocating Memory • When you initialize a new process, the runtime reserves a contiguous region of address space for the process – This reserved address space is called the managed heap • The managed heap maintains a pointer to the address where the next object in the heap will be allocated – We’ll call this the NextObjPtr – All reference types are allocated on the managed heap 329 ENEL712-Embedded Systems Design Allocating Memory (Continued) • An application creates an object using the new keyword • The new operator first makes sure that the bytes required will fit in the reserved region (it will add space if required) Managed Heap – If the object fits, then NextObjPtr points to the new object, and the object’s constructor is called • Next, NextObjPtr is incremented past the object, so it now points to where the next object will be placed – This process repeats as long as address space is available 330 ENEL712-Embedded Systems Design Comparison with a C Heap • Previously we defined the heap as a room full of boxes, in no particular order, except in positions big enough to contain all the boxes (objects) – This is a C-runtime heap (not a managed heap) • In actuality, the ‘room’ is described as a linked list (a special kind of list in C) – Every time new is called, the list must be searched for a block of memory large enough to store the object – The block is then split into the correct size, and the list’s nodes updated with the new memory information • In comparison with a managed heap, all objects are stored consecutively (contiguously), and a single pointer determines where the next object will fit – This means allocating memory from a managed heap is much faster – In fact it is almost as fast as on the Stack (LIFO queue) 331 ENEL712-Embedded Systems Design The Garbage Collection Algorithm • The Garbage Collectors job is to determine what objects are no longer required (garbage), and free the memory so it can be used again (collect and reclaim) • But how does GC know when an object is no longer required? – It turns out to be a little complex 332 ENEL712-Embedded Systems Design Application Roots • Every application has a set of roots. Roots identify storage locations, where refer to objects on the managed heap • Application roots include: – All global and static object pointers in an application – Local variable object pointers on a thread’s stack – Any CPU registers containing pointers to objects in the managed heap • The list of active roots is maintained by the Just-In-Time (JIT) compiler and CLR – This list is made available to the Garbage Collection algorithm, so it can determine what is being used! 333 ENEL712-Embedded Systems Design GC Step 1: Build Object List • Interestingly, when GC starts, it makes the assumption all objects are garbage (i.e. they are unreachable objects) • The algorithm begins by searching each of the application roots, looking for objects on the managed heap – As it finds a reachable object, it adds it to it’s list (technically it builds a graph) • In the example to the right, objects A, C, D and F all contain application roots. Object H is pointed to be D, therefore is also added to the GC list – The remaining objects are deemed unreachable, and are garbage! 334 ENEL712-Embedded Systems Design GC Step 2: Free Unreachable Objects • Once the GC list of reachable objects is complete the algorithm begins linearly searching through the managed heap – As it searches it is looking for contiguous blocks of garbage objects (free space) – The GC shifts non-garbage objects down in memory, overwriting the existing garbage memory, and reclaiming memory! NextObjPtr is realigned after GC is complete • However, by moving the non-garbage objects, we invalidate all pointers to the objects – Therefore the final step of GC is it must modify the application’s roots so that the pointers all point to the correct locations – It must also correct pointers held by objects 335 ENEL712-Embedded Systems Design GC Performance Overhead • While allocating memory is more efficient, releasing it via GC generates a significant performance hit – This is a major downside of using a managed heap • However, the GC algorithm contains an optimizing engine which determines the best time to perform GC – Typically only performed when the heap is full • There are also other optimizations: – Generational Garbage Collection (based on how long an object exists), this allows selective root searching – Partial heap compacting, rather than full heap – Large objects are maintained in a separate heap, and not compacted 336 ENEL712-Embedded Systems Design Implications of GC on Pointers • The use of pointers is rarely required in C# – This is due to all dynamically allocated memory being allocated and released using Garbage Collection • However let’s consider the implication of if we did use a pointer in C# (if we were allowed to) – double *x = new double[4]; • If GC was used to allocate the memory for x, this would be OK – But what would happen once GC had compacted our managed heap? – Remember x contains an address in memory that would not be updated by GC… 337 ENEL712-Embedded Systems Design Unsafe Code • As it turns out, you can use pointers in C# – But only if you declare the method they are used in as unsafe – And the entire project must be compiled with the /unsafe option static unsafe void Copy(byte[] src, int srcIndex, byte[] dst, int dstIndex, int count) • It is however discouraged, and you should avoid using them if you can! – This results in the method not being defined as ‘safe’ by the CLR, and may restrict where it can be executed • For a managed data type that supports pointer functionality conside using a GCHandle – The managed data type GCHandle which allows for ‘pinned’ memory (objects which GC does not move) 338 ENEL712-Embedded Systems Design .NET Summary • The .NET Framework is a free software framework which allows: – Faster development via powerful supplied types and classes – Safer, more secure code – Multi-platform deployment – Not limited to application development, but also Web, Database, Cloud and others – Built on CLI, an internationally recognised standard – Available from C++, C#, VB.NET, J# 339 Lecture 19 C# Basics ENEL712-Embedded Systems Design C# Fundamentals • C# follows generally the same syntax as C++: – All statements must end in a semicolon (;) – White space or new line do not declare the end of a statement, statements may exist over multiple lines – All identifiers (variables, methods, classes) are case sensitive – Identifiers must start with a letter or underscore – Comments use // or /* … */ 341 C# Reserved Keywords ENEL712-Embedded Systems Design abstract do in protected true as double int public try base else interface readonly typeof bool enum internal ref uint break event is return ulong byte explicit lock sbyte unchecked case extern long sealed unsafe catch false namespace short ushort char finally new sizeof using checked fixed null stackalloc virtual class float object static void const for operator string volatile continue foreach out struct while decimal goto override switch default if params this delegate implicit private throw 342 ENEL712-Embedded Systems Design Naming Variables • It is good practice to adopt a naming strategy for variables – Don’t start with an underscore – Don’t create variables that vary only by case • e.g. var and Var – Start the name with a lowercase letter – For multiword variables, use “camelCase” notation: • e.g. myVar, mp3Writer, fileID 343 ENEL712-Embedded Systems Design Unassigned Local Variables • A common error is to use a local variable before you have assigned it a value: int age; Console.WriteLine(age); //compile error • In C++ you would write the last piece of information left over at that memory address (basically rubbish) – In C# you get a compile-time error indicating age is unassigned! – This is quite useful in complex conditional statements where a variable may not be initialized by all code paths – Also consider the need for a default case statement… 344 ENEL712-Embedded Systems Design C# Data Types Data Type Description Size (bits) Range byte Whole Numbers 8 0 to 255 int Whole Numbers 32 -231 to 231-1 long Whole Numbers 64 -263 to 263-1 float Floating Point 32 double Floating Point 64 decimal Monetary Values 128 string Sequence of Chars 16 per char char Single Character 16 0 to 216-1 bool Boolean 8 True or false 28 s.f. • There are also a number of other data types, however these are the main ones 345 ENEL712-Embedded Systems Design Type Casting • When converting between data types there is also a precedence to consider: double d = 1.2; float f = 1.2F; d = f; f = d; f = (float)d; //OK – implicit float to double //ERROR – no implicit cast exists //OK – explicit cast used • Basic rule of thumb – If you are going to lose information in the assignment you should use a type cast • This tells the compiler you know what you are doing! – In some cases it may also be required 346 ENEL712-Embedded Systems Design Converting Strings -> Numbers • Typical operation when working with GUIs – User enters a ‘number’ in a textbox, but it is stored as a string int x = Convert.ToInt32(“strNumber”); int y = Int32.Parse(“strNumber”); • Both give identical results except when the string is a null – Convert() will return 0, Parse() will throw an exception 347 ENEL712-Embedded Systems Design Converting Numbers -> Strings • All data types contain a method to convert them to a string: int x = 2; float y = 2.2; string s1 = x.ToString(); string s2 = y.ToString(“0.00”); //2 decimal places 348 ENEL712-Embedded Systems Design Passing By Reference • When you pass an argument to a method, the corresponding parameter is initialized with a copy of the argument void doIncrement(int param) { param++; } • In the above example, although legal C# code, it does not increment the variable in the calling function – It increments the local copy in the function, which is then deleted when the function returns! • In order to provide the ‘handle’ or pointer functionality of C++, C# allows you to pass a variable by reference 349 ENEL712-Embedded Systems Design ref Keyword • Below is the same code snippet, this time using ref: void doIncrement(ref int param) { param++; } • This time the argument param is the same object in the calling function, and our local function – This allows us to increment it within our function, and have the value change in the calling fuction. • This is called passing by reference, as you are passing a reference to the existing object (opposed to a copy of it) – Similar analogy to pointers and passing a memory address 350 ENEL712-Embedded Systems Design out Keyword • Passing by reference also works with unassigned variables using the out keyword: void doInitialize(out int param) { param = 5; } • The above example allows us to initialize the argument within a function. For example: int age; //unassigned local variable doInitialize(out age); //use of out • This example would not work with ref, because ref requires the variable to be initialized. 351 ENEL712-Embedded Systems Design Operator Precedence Category Operators Primary x.y f(x) a[x] x++ x-- new Unary + - ! ~ ++x --x (T)x Multiplicative * / % Additive + - Shift << >> Relational < > <= >= is as Equality == != Logical & ^ | Conditional && || ?: Assignment = *= /= %= += -= <<= >>= &= ^= |= • Operators in the same row are read from left to right – Remember if in doubt – use brackets! 352 ENEL712-Embedded Systems Design Mathematical Functions • Mathematical functions are part of the static System.Math class: Abs Cos Min Acos Exp Pow Asin Floor Round Atan Log Sin Atan2 Log10 Sqrt Ceiling Max Tan • e.g. – double x = Math.Abs(-5); – Alternatively you can include the System.Math namespace to avoid using “Math.” 353 ENEL712-Embedded Systems Design Random Number Generation • We can use the Random class to generate pseudo-random numbers: Random randObj = new Random(); int x = randObj.Next(); int y = randObj.Next(5); double z = randObj.Next(); //create object //random integer //integer 0 to 4 //random double • How did the last statement know to generate a random floating point number? • Is this a static class? Why / why not? 354 ENEL712-Embedded Systems Design Date and Time • A common programming task is to retrieve the current date and time, or calculate the date / time at some future event – A real pain with varying month lengths, leap, years, 365 ¼ days, etc! • Use the DateTime class to do the hard work! DateTime dateObj = DateTime.Now; //current date + time Console.WriteLine(dateObj.ToString()); //display current date dateObj.AddDays(5); //add 5 days to the current date 355 ENEL712-Embedded Systems Design Exception Handling • One of the most useful updates from C to C++ was exception handling. – This allows you to gracefully catch program errors due to users, bad code or bad data • In C# exception handling is very similar to C++, however as expected it is easier! • Exception handling is recommended when: – – – – Reading and writing files Getting data from the user Accessing a database Other non-deterministic events (i.e. you as the programmer cannot control what form information may be passed to you) 356 ENEL712-Embedded Systems Design try and catch • A common use of error catching is to alert the user about entry errors: try { int num1 = Convert.ToInt32(textBox1.Text); } catch(FormatException) //which error does this catch? { MessageBox.Show(“Please check your entry!”); } 357 ENEL712-Embedded Systems Design Catching all Exceptions • If you do not want to specify which exceptions you want to catch, use the following: try { int num1 = Convert.ToInt32(textBox1.Text); } catch(Exception ex) //catches all exceptions and stores in ‘ex’ { MessageBox.Show(“Please check your entry! Error: ” + ex.Message); } 358 ENEL712-Embedded Systems Design Programming Exercise • For the remainder of the class I want you to write a C# GUI that has the following specifications: – On Tab 1: • Using a ComboBox and the 7-segment display from the assignment, allow the user to select a number from 0-F and have it be automatically drawn on the 7-segment display. – On Tab 2: • Using a numeric up/down and a multiline textbox, print the Fibonacci numbers from 0 to the value in the numeric up/down in the multiline textbox 359 ENEL712-Embedded Systems Design What is an Array? • An array is an unordered sequence of elements – The elements live in a contiguous block of memory – Elements are accessed by using an integer index • All elements have the same name and same data type – So you don’t have to think of a different name for every element! – Also allows you to access any element from a single object 360 ENEL712-Embedded Systems Design Declaring Array Variables • Declaring arrays is similar to C++, however note the location of the square brackets: int[] pins; //declare an array of pins • Remember declaring an array does not create it! – Memory is only created for the object when you call the new keyword. – The above code only creates a single reference type to reference the array memory once it is created 361 ENEL712-Embedded Systems Design Creating an Array Instance • You can create an instance of an array using the new keyword as follows: int[] pins; pins = new int[4]; //declare an array of pins //an array of 4 integers • new is an example of dynamic memory allocation, i.e. memory which is allocated at runtime – Remember using C# means any dynamically allocated memory will be automatically deleted for us – The alternative is static memory, i.e. an array with a fixed size that is declared at design time 362 ENEL712-Embedded Systems Design The Stack • When we create an array (or any class object) the location of array variable (reference) and array memory (elements) are different • The array variable is placed on the Stack – The Stack memory is organized like a stack of boxes piled on top of one another – When a method is called each argument is placed in a box on top of the stack. – Each local variable is also placed in a box on top of the stack. – When the method finishes, all created boxes are removed – The CPU maintains a Stack Pointer to know where in memory to be reading / writing from 363 ENEL712-Embedded Systems Design The Heap • The array memory is placed on the Heap – The Heap memory is not organized, it is like a room with boxes strewn around it – Each box contains a label indicating whether it is in use – When a new object is created, the runtime searches for an empty box (or boxes) and allocates it to the object – The reference to the object is stored on the Stack – The runtime keeps track of the number of references to a box, when no more references exist, the box is labelled as empty 364 ENEL712-Embedded Systems Design Our Array Instance in Memory STACK HEAP int[] pins int[] pins; ? int[] pins pins = new int[4]; @ 0 0 0 0 365 ENEL712-Embedded Systems Design Initializing Array Variables • When creating an array C# will automatically initialize all elements based on the data type (typically 0 for numeric types) • However you can modify this behaviour: int[] pins = new int[4] {9, 3, 7, 2}; OR int[] pins = {9, 3, 7, 2}; //typical way • In the last line of code, the compiler will automatically determine the correct size of the array. 366 ENEL712-Embedded Systems Design Iterating through An Array • To set or get the elements of an array we can use a for loop – Just remember C# indices start at 0! int[] pins = {9, 3, 7, 2}; for (int index = 0; index < pins.Length; index++) { int pin = pins[index]; //get element [index] Console.WriteLine(pin); } • Note the use of the property Length. A C# array is like a C++ .NET Array<type>, in which you can access the length as a property of the array – The C# array also has methods such as sum and average which can operate on the whole array 367 ENEL712-Embedded Systems Design foreach Statement • C# also includes the foreach statement for iterating through all elements in an array: int[] pins = {9, 3, 7, 2}; foreach (int pin in pins) { //At each iteration “pin” will be the next element, starting from the beginning Console.WriteLine(pin); } 368 ENEL712-Embedded Systems Design Copying Arrays • Creating a copy of an array may seem a trivial task: int[] pins = {9, 3, 7, 2}; int[] alias = pins; //not a copy! • In fact the above code is wrong. Both pins and alias both refer to the same array memory! – You must create new memory for the copy and then copy the existing elements into it – This is because the array is a reference type. int[] copy = new int[pins.Length]; pins.CopyTo(copy, 0); //array method to copy contents 369 ENEL712-Embedded Systems Design Multidimensional Arrays • As well as single dimensional arrays (vectors), C# can also handle multidimensional arrays (matrices and above) int[,] items = new int[4, 6]; //4x6 matrix int[, ,] cube = new int[5,5,5]; //5x5x5 array items[2,3] = 99; cube[1,2,1] = 101; //set element (2,3) to 99 370 ENEL712-Embedded Systems Design Jagged Arrays • A further feature of multidimensional arrays in C# is the ability to create jagged arrays – Allows arrays which aren’t rectangular… – Although this is typically bad practice! int[][] jagArr = new int[2][]; //jagged array declaration jagArr[0] = new int[2]; //1x2 array jagArr[1] = new int[4]; //1x4 array jagArr[0][1] = 9; jagArr[1][3] = 10; //last element in array 0 //last element in array 1 371 ENEL712-Embedded Systems Design Parameter Arrays • Sometimes you may want to write methods that can take a variable number of arguments – This is different from overloading a method – An example is writing to the console • The solution is to use a parameter array in the function declaration – Within the function you will receive an array filled with the arguments supplied 372 ENEL712-Embedded Systems Design Parameter Array Example • The following code example finds the minimum of the supplied integer arguments int Min(params int[] paramList) { int currentMin = paramList[0]; foreach(int i in paramList) { if(i < currentMin) currentMin = i; } return currentMin; } • This function can be called as follows: int x = Min(1,2,3) int y = Min(1,2,3,4,5) //3 arguments //5 arguments OK too! 373 Lecture 20 C# Strings, Structures and Collection ENEL712-Embedded Systems Design What is a String? • A string is a special type of an array that holds characters – A C# character is a 16bit data type that holds data in UTF-8 format (backwards compatible with ASCII) • Strings are defined in C# using double quotes: – “This is a string” • The string data type can be used to store a string of any length (provided it fits in memory): – string str1 = “This is a string”; – string str2 = “This is a longer string”; 375 ENEL712-Embedded Systems Design Concatenating Strings • Concatenating strings (joining one string onto the end of another) is easy in C# – Use the + operator – Commonly used when displaying variables to the user: int x = 2; //The variable to display MessageBox.Show(“The Value is: ” + x.ToString()); 376 ENEL712-Embedded Systems Design Substring Method • You can extract part of a string using the Substring() method – This requires you to know the starting index and number of characters to read string str = “This Is A String”; //Displays “This” MessageBox.Show(str.Substring(0,4)); //Displays “ Is ” MessageBox.Show(str.Substring(4,4)); • Alternatively, to extract just one character from a string, you can index into it: char c = str[0]; //Returns ‘T’ 377 ENEL712-Embedded Systems Design IndexOf Method • To determine if one string is contained within another you can use the IndexOf() method – The method returns the index of where the string was first found, or -1 if it can’t find it – Be careful as this is a case sensitive search string str = “I like bacon”; int index1 = str.IndexOf(“bacon”); //returns 7 int index2 = str.IndexOf(“Bacon”); //returns -1 378 ENEL712-Embedded Systems Design Dealing with Spaces • Use the following functions for removing spaces from strings: – Trim() Remove spaces from the beginning and end of a string – TrimEnd() Remove spaces from the end of a string – TrimStart() Remove spaces from the beginning of a string – Remove() Remove a specified number of spaces from a position in a string 379 ENEL712-Embedded Systems Design Replace Method • Substrings can easily be replaced with the Replace() method – e.g. replacing .wav with .mp3! string filename = “sublime.wav”; string outfile = filename.Replace(“.wav”,”.mp3”) 380 ENEL712-Embedded Systems Design Split Method • A common string processing job is to split an existing string into substrings or words – For example splitting a Comma-Separated Values (CSV) file into entries – You specify the delimiter (what to split by) as part of the calling arguments string str = “Sally,Bob,Frank”; char delimiter = ‘,’; //note single quotes for a character string[] names = str.Split(delimiter); //returns an array of 3 strings 381 ENEL712-Embedded Systems Design Programming Exercise • Take the following string and ‘decode’ it using C#: – "g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle." – Hint – Think in ASCII! – Use a C# Console Application and print the solution to the console 382 ENEL712-Embedded Systems Design Structures • While arrays are good for storing many elements of the same data type, structures allow you to store elements of multiple data types – For example a phonebook entry requires a name (string) and a phone number (integer) – Like with classes, structures can also contain a constructor and methods • The main difference between a structure and a class is where the information is stored in memory – All structure information is stored on the stack • This can be more efficient for small structures 383 ENEL712-Embedded Systems Design Declaring a Structure • Structures are defined using the struct keyword followed by the name of the type and the body of the structure, as follows: struct Time { public int hours; public int minutes; public int seconds; } • This structure can then be used as follows: Time currentTime; //create a new instance of the Time structure currentTime.hours = 5; //setting the field of the structure 384 ENEL712-Embedded Systems Design Structure Constructor • You can also create a constructor which can initialize the fields of a structure: struct Time { public int hours, minutes, seconds; public Time(int hh, int mm, int ss) { hours = hh; //assign constructor variables minutes = mm; seconds = ss; } } • However, unlike a class, you must initialize all fields when using a structure constructor 385 ENEL712-Embedded Systems Design Structures in Memory • Called without the constructor, fields are not initialized Time now; now.hours ? now.minutes ? now.seconds ? • Called with the default constructor Time now = new Time(); STACK STACK now.hours 0 now.minutes 0 now.seconds 0 HEAP Structures are value types, they are stored on the Stack. HEAP 386 ENEL712-Embedded Systems Design Copying Structure Variables • Because a structure is a value type, you may copy a structure as you would expect: Time now = new Time(); Time copy = now; //copy ok • This only applies if the structure is initialized, otherwise a compiler error will be generated – The same would occur if you were trying to copy an unassigned int! 387 ENEL712-Embedded Systems Design Programming Exercise • Create a ‘Pixel’ structure than can hold an RGB (Red,Green,Blue) and HSV (Hue,Saturation,Value) triplet – R,G,B,S,V all vary from 0-1 (or 0-255 if you prefer) – H may be in degrees, or 0-1 if you prefer • Create a constructor that allows initialization of the RGB values. • Create methods to: – Convert from RGB -> HSV (called from the above constructor) – Print the Pixel (both in RGB and HSV) • Use the following page to derive the required equations: – http://www.rapidtables.com/convert/color/rgb-to-hsv.htm • Write a test program to check the operation of your structure – Use Red, Green, Blue, Yellow, Cyan and Magenta 388 ENEL712-Embedded Systems Design Collection Classes • Arrays are incredibly useful, but the developer can be limited by the requirement to use an integer index • An alternative from the .NET Framework is to use a Collection – Although more complicated, Collections allow for better management of lists – A Collection holds a collection of objects, allowing for any type to be stored 389 ENEL712-Embedded Systems Design Arrays vs Collections in Memory STACK • Int Array @ HEAP 9 7 3 2 int[] array = {9,7,3,2}; • Object Array STACK HEAP 7 @ object[] array = {9,7,3,2}; @ 9 @ 2 @ 3 @ 390 ENEL712-Embedded Systems Design The ArrayList Collection Class • If you need to shuffle elements around in an array or be able to insert and remove elements, an ArrayList might be useful – Located in the System.Collections namespace ArrayList numbers = new ArrayList(); //fill the array foreach(int number in new int[4] {1, 2, 3, 4}) { numbers.Add(number); //note adding new elements is ok! } 391 ENEL712-Embedded Systems Design ArrayList: Inserting & Removing Elements //Insert an element at the end numbers.Insert(numbers.Count,5); //Remove the last element numbers.RemoveAt(numbers.Count); //Iterate through elements for(int i = 0; i < numbers.Length; i++) { int number = (int)numbers[i]; //notice the cast Console.WriteLine(number); } 392 ENEL712-Embedded Systems Design Programming Exercise • Using an ArrayList and a Random object: – Insert 100 random doubles into the ArrayList – Sort the array (smallest number first) – Print the elements to the command window using a foreach loop 393 ENEL712-Embedded Systems Design Other Collection Classes • As well as the ArrayList, there are also a number of other Collection classes: • Queue Collection – Implements a First-In, First-Out (FIFO) collection • Stack Collection – Implements a Last-In, First-Out (LIFO) collection • Hashtable Collection – Implements a collection where you can index using any data type • SortedList Collection – Same as a hashtable, except always sorted by keys • Dictionary Collection – Similar to a Hashtable, but more generic and typically faster (and newer) 394 ENEL712-Embedded Systems Design The Dictionary Collection Class • ArrayList is useful as a more flexible array – I.e. being able to sort, add and remove elements – But it still requires an integer index • So you must know where the data is that you require • A Dictionary on the other hand is a much more powerful Collection – Values are stored as Key-Value pairs • A key is used to identify the value, rather than its position within the collection – Looking up values is done via the Key • Using a Hash Table the look-up is really fast – Keys can be strings or integers – Values can be any data type, as long as it is consistent for all values • Dictionaries are also known as associative arrays in other languages, and I use them quite a bit – Another useful data type to add to your programming knowledge 395 ENEL712-Embedded Systems Design Dictionary Example • A Dictionary to hold the names of common prerequisites for deploying software: Can be any data type Dictionary<string,string> prereqs = new Dictionary<string,string>(); prereqs.Add("VS2013","Visual Studio 2013"); prereqs.Add("VS2012","Visual Studio 2012"); prereqs.Add("VS2010SP1","Visual Studio 2010 SP1"); Key (Must be Unique) Value (May be Duplicated) Console.WriteLine("Required PreReq: {0}",prereqs["VS2013"]); Note Key is used as Index! • Very efficient for looking up data, and easier! 396 ENEL712-Embedded Systems Design Programming Exercise • Using a Dictionary: – Create a Phone Book Application • The application queries the user for a name and phone number from the Console • It then saves it within a Dictionary • After every save, it displays the full phone book, then queries for more names+numbers – Use Console.ReadLine to read text from the Console http://www.dotnetperls.com/dictionary 397 Lecture 21 Graphical User Interface Controls, Properties, Events ENEL712-Embedded Systems Design The Graphical User Interface (GUI) • This is how the user interacts with your program – Very important if you are developing for a client! • Nearly all of the controls you will need are provided by Visual Studio – Drag, drop, program, use! • Custom controls are available – Simply Google, chances are someone has already written what you need – E.g. the LEDs and 7-segment display in the assignment 399 ENEL712-Embedded Systems Design Example GUI Windows Form Labels Month Calendar Text boxes Buttons Charts Text Box Combo Box Picture Box 400 ENEL712-Embedded Systems Design Common Controls • Commonly used controls are listed under “Common Controls” in the Toolbox – The toolbox can be found on the left hand side bar of VS • A complete list of all Windows Forms controls is listed under “All Windows Form” • Simply click and drag the control you want onto your form to use it 401 ENEL712-Embedded Systems Design The Label • Use – Information text – Can be changed by the program, but not by the user • Main Properties – Text 402 ENEL712-Embedded Systems Design The Button • Use – Do something when the user clicks on it • Main Properties – – – – – Appearance – Color, Text Behavior - Enabled, Visible Data - Tag Design - Name Layout – Location, Size • Main Events – Click 403 ENEL712-Embedded Systems Design The TextBox • Use – Allow the user to type text, or for displaying text • Main Properties – – – – – Text (single line) Lines (multiline) MultiLine ReadOnly Others – Autocomplete • Main Events – Keyboard – TextChanged – Focus – Enter, Leave 404 ENEL712-Embedded Systems Design Using a TextBox Single Line: MultiLine: //Setting Text textBox1.Text = “Hello”; //Setting Text: adds to new line textBox1.AppendText(“\r\nHello”); //Getting Text: from Line 0 //Getting Text string myStr = textBox1.Text; string myStr = textBox1.Lines[0]; //Reading a Number int a = Int32.Parse(textBox1.Text); //Number of Lines int len = textBox1.Lines.Length; Remember data is always a string! 405 ENEL712-Embedded Systems Design String Conversions • Commonly we want to convert between a string and a numeric type and vice-versa – For example reading a textbox value //String to Number int x = Int32.Parse(string); int x2 = Convert.ToInt32(string); //alternative //Number to String string str = x.ToString(); 406 ENEL712-Embedded Systems Design The ComboBox • Use – Allows the user to select from a list of values • Main Properties – Text (Selected Text) – Items (Collection) • Main Events – SelectedIndexChanged – DropDownClosed – Click 407 ENEL712-Embedded Systems Design Using a ComboBox • The List of items can be created at design time (when you are writing the program) or at run time (once the application is running) – Typically we will do it at design time via the designer – Simply fill in the ‘collection’ with the list items //Reading the Bitrate from a ComboBox uint bitrate = uint.Parse(comboBox1.Text); 408 ENEL712-Embedded Systems Design More Controls • Controls – Radio Buttons – Check Boxes – Numeric Up Down 409 ENEL712-Embedded Systems Design The RadioButton • Use – Selecting one value from many – Typically placed in a container (e.g. panel, group box) • Main Properties – Text – Checked • Main Events – CheckedChanged 410 ENEL712-Embedded Systems Design The CheckBox • Use – Selecting as many values as needed – Can be placed in a container • Main Properties – Text – Checked • Main Events – CheckChanged – CheckStateChanged 411 ENEL712-Embedded Systems Design The Numeric Up Down • Use – Select integer numbers from a range • Main Properties – Maximum – Minimum – Value • Main Events – ValueChanged 412 ENEL712-Embedded Systems Design Containers • Containers provide a means to group controls together – You can enable / disable groups of controls via a container • You can also create tabbed programs using the TabControl 413 ENEL712-Embedded Systems Design The GroupBox • Use – Group common controls into a box – Typically aesthetic, but also useful from code • Main Properties – Text (Title bar text) 414 ENEL712-Embedded Systems Design The TabControl • Use – Grouping controls into tabbed pages • Main Properties – Collection • Use the TabPage Collection editor to edit your pages 415 ENEL712-Embedded Systems Design Non-Visual Controls • Not all controls are visible on the Form – Instead they are placed in the designer tray • Examples – File Dialog boxes – Menu Strips – Timers • However you still drag them onto your form from the Toolbox to create them Designer Tray 416 ENEL712-Embedded Systems Design Control Naming • VERY important! – The default names assigned by VS are: • textBox1, textBox2, etc – These names are not easy to remember • Is textBox1 the opened file, or the saved file? – If you change the Name property you can assign any unique string to the control: • openTBox, saveTBox • BUT you must change the name BEFORE you create any events for the control! Otherwise VS will not find them. – You can fix this, but it is a pain! 417 ENEL712-Embedded Systems Design Event Driven Programming • Windows is an event driven system – An event is something the computer must respond to, such as a mouse click or key press • The computer cannot predict what event will occur next and thus must be able to respond correctly to any event – This is different to console programming from year 1! – Console programs prompt the user to enter information if required 418 ENEL712-Embedded Systems Design Event Handlers • When Windows receives an event (e.g. mouse click) it creates a message for this event and places it in the message queue of the program the event is for • Writing Windows GUI applications consists of writing functions to respond to these events – These functions are called event handlers – Visual Studio makes it easy to link our event handlers to the Windows message queue 419 ENEL712-Embedded Systems Design Example Project: Calculator • The next few slides give an example of a 4 function calculator using Visual C# and .NET • Get started by creating a new Visual C# Windows Forms Application – Give the project a suitable name and save it to a local drive (Not H:\ Drive) 420 ENEL712-Embedded Systems Design Calculator: Form Design • Add 3 text boxes, 4 buttons and one label to the form – Each button should be 40x40, 14pt font, and named appropriately – Each text box should be 12pt font and named appropriately • Arrange the controls as per the example At any point you can press F5 to run your program 421 ENEL712-Embedded Systems Design Calculator: Addition Event Handler • Double click on the + button to automatically create a click event handler: – Note I have called my addition button “plusB” private void plusB_Click(object sender, EventArgs e) { } • Using this event handler we can program what happens when the user clicks on the + button! 422 ENEL712-Embedded Systems Design Calculator: Addition Event Handler • Add the following code to your addition event handler: – Note the naming of my textboxes! private void plusB_Click(object sender, EventArgs e) { double sol = double.Parse(aTBox.Text) + double.Parse(bTBox.Text); //calculate result cTBox.Text = sol.ToString(); //place result in the sol text box } • Press F5 to run your program and test the addition button! 423 ENEL712-Embedded Systems Design What Does Our Code Do? private void plusB_Click(object sender, EventArgs e) { double sol = double.Parse(aTBox.Text) + double.Parse(bTBox.Text); //calcualte cTBox.Text = sol.ToString(); //place result in the sol text box } • Every time you click the addition button the above function is called by Windows – This is the event handler – Windows also passes two arguments to the function, we can ignore them for now • Inside the function we convert the strings in each input textbox to a double, add them, then convert the solution back to a string and write it to the output textbox. 424 ENEL712-Embedded Systems Design Simple Error Catching • Try entering a string, or leaving one of the input textboxes empty – The program crashes (not very robust!) • However we can use error catching to stop the program crashing! – This is done using try{} and catch{} 425 ENEL712-Embedded Systems Design Calculator: Error Catching • Replace your addition event handler code with the following: private void plusB_Click(object sender, EventArgs e) { try { double sol = double.Parse(aTBox.Text) + double.Parse(bTBox.Text); cTBox.Text = sol.ToString(); } catch (Exception ex) { MessageBox.Show("Error Parsing Input Text: " + ex.Message,"Parsing Error",MessageBoxButtons.OK); } } 426 ENEL712-Embedded Systems Design What Does Our Code Do? try { double sol = double.Parse(aTBox.Text) + double.Parse(bTBox.Text); cTBox.Text = sol.ToString(); } catch (Exception ex) { MessageBox.Show("Error Parsing Input Text: " + ex.Message, "Parsing Error",MessageBoxButtons.OK); } • When an error is found in double.Parse() it throws an exception. If this exception is not “caught”, it will cause the program to crash. – However if you place a try{} catch{} statement around the parse statements, if an exception is thrown you can catch it. – In the above example we catch ALL exception types (Exception ex), however you can catch specific exceptions and deal with them individually. • Finally a MessageBox is shown to the user with a copy of the error message. 427 ENEL712-Embedded Systems Design Calculator: Completing The Application • We could copy and paste the code so far into event handlers for each button – However if you find yourself copying and pasting the same code you should probably use a function! • Lets create a new method which does the parsing and calculation for us, including error catching 428 ENEL712-Embedded Systems Design Calculator: Calculation Method private string doCalculation(string a, string b, string op) { double c_num = double.NaN; //good initialization value! try { double a_num = double.Parse(a); double b_num = double.Parse(b); //Calculate based on operator switch(op) { case "+": c_num = a_num + b_num; break; case "-": c_num = a_num - b_num; break; case "*": c_num = a_num * b_num; break; case "/": c_num = a_num / b_num; break; } } catch(Exception ex) { MessageBox.Show("Error Parsing Input Text: " + ex.Message, "Parsing Error", MessageBoxButtons.OK); } return c_num.ToString(); } 429 ENEL712-Embedded Systems Design Calculator: Revised Addition Event Handler • Now we have a function completing the ‘guts’ of the application, our event handler is one line: private void plusB_Click(object sender, EventArgs e) { cTBox.Text = doCalculation(aTBox.Text, bTBox.Text, "+"); } • Repeat the process for the other buttons, adding the respective function call as above – And you’re finished! 430 ENEL712-Embedded Systems Design Dialogs • The MessageBox class we used is an example of a dialog – This is the easiest way to display text information to the user – Remember it is not a control 431 ENEL712-Embedded Systems Design MessageBox Class • There are several ways to call the MessageBox.Show method: MessageBox.Show("Error"); MessageBox.Show("Error", "Parse Error"); MessageBox.Show("Error", "Parse Error", MessageBoxButtons.OKCancel); MessageBox.Show("Error", "Parse Error", MessageBoxButtons.OKCancel, MessageBoxIcon.Error); This is an example of OOP 432 ENEL712-Embedded Systems Design Multiple Forms • Your application can consist of more than one Windows Form – You can either create it from the Solution Explorer or via code • If you create it programmatically, you will need to code the location of all controls! – Hence the term Visual C# for performing this task via the designer! Form form2 = new Form(); form2.Show(); 433 ENEL712-Embedded Systems Design Inter-Form Control Access • This is an advanced topic, only for interest • Each control is declared as a private data member of its respective Form (check Form1.Designer.cs): private System.Windows.Forms.TextBox aTBox; • This means another class (or Form) cannot access this property – However you can create a public method that allows access to the control: public void write_aTBox(string new_text) • The same concept applies to any class, private data members cannot be accessed outside the class – This is the concept of encapsulation 434 Lecture 22 File Handling & Serial Ports ENEL712-Embedded Systems Design File Types • Most programs will require the ability to read and or write to files – Writing a log file of measurements – Reading data to plot it – Importing data to process it • There are two typical file types we will deal with – Text (ASCII or Unicode) • What you create in notepad – text files with characters limited to those in the ASCII table (or Unicode) – Binary • Files of 0s and 1s that can’t be displayed as text • e.g. applications, bitmaps, wave files 436 ENEL712-Embedded Systems Design Files and Streams • C# views files as a sequential stream of bytes – The file ends with an EOF marker or after a certain byte count • C# contains a number of classes for reading and writing files (both ASCII and binary) – Each class stores the current file it has open as a stream object – A stream stores the file as a sequence of bytes, as well as the current position to read from / write to – It contains properties such as length, file mode access, etc – And contains methods such as read, write, open, close • We have already used streams in previous courses! – cout writes to the standard output stream – cin reads from the standard input stream – Both are derived from the iostream class (remember include iostream.h?) 437 ENEL712-Embedded Systems Design StreamReader Class • For general text reading we can use a StreamReader object – Derived from the TextReader class • The StreamReader is designed for character input in a particular encoding (e.g. ASCII) – The Stream class is designed for byte input and output, as opposed to a numbers of bits //Open a text file for reading StreamReader sr = new StreamReader(“test.txt”); //Reads the first line from the file and displays it Console.WriteLine(sr.ReadLine()); //Close the file stream sr.Close(); 438 ENEL712-Embedded Systems Design StreamWriter Class • For general text writing we can use a StreamWriter object – Derived from the TextWriter class • As with the StreamReader, the StreamWriter is designed for character output in a particular encoding. – It is not normally used for binary file writing (e.g. an mp3 file!) //Open a text file for writing StreamWriter sw = new StreamWriter(“test_out.txt”); //Writes a line to the file sw.Write(“Hello ”); sw.WriteLine(“World!”); the end //this method adds a CR + LF to //Close the file stream sw.Close(); 439 ENEL712-Embedded Systems Design FileStream Class • The FileStream class is derived from the Stream Class, and allows us to read or write to a file in bytes //Open an existing file for reading Stream inStream = new FileStream(fileName, FileMode.Open); //Create a new file for writing Stream outStream = new FileStream(fileName, FileMode.Create); • As well as supplying the constructor with the filename we want to open, we must also supply the FileMode – This tells the class how we want to work with the file – Options include Append, Create, Open, and others • A FileStream object is useful for creating a Stream object from a file – The Stream object can then be used by other classes. 440 ENEL712-Embedded Systems Design BinaryReader Class • A BinaryReader is used for reading binary data from a Stream – The data could be text, but most likely it is a series of bytes (e.g. 8, 16, 32 or 64 bits) – The easiest way to read this data by eye is viewing it as HEX, e.g. 0x48, 0x45, 0x4C with a HEX editor • All compiled programs on your computer are in binary format – As are most file formats (jpeg, png, wav, mpeg, etc) – The binary content is only meaningful to programs that expecting a certain data format • An example is a .wav file, which contains the audio data (PCM) as a sequence of bytes – Every 16 bits is a number representing the amplitude at a particular sample, on one channel – Remember we typically listen to 44.1kHz audio, that’s 44,100 x 2 channels x 16 bits per second! 441 ENEL712-Embedded Systems Design BinaryReader Example • For example, reading a string of 4 ASCII characters from a binary file: //Open the File and pass to a Binary Reader Stream InStream = new FileStream(“test.txt”,FileMode.Open); BinaryReader Reader = new BinaryReader(InStream); //Create an array to store the data in byte[] chunk = new byte[4]; //Read in 4 bytes Reader.Read(chunk,0,4); //we could also use ReadInt8() 4 times //Convert the data to a string, using ASCII encoding string str = Text.Encoding.ASCII.GetString(chunk); //Close the File InStream.Close(); 442 ENEL712-Embedded Systems Design BinaryWriter Class • A BinaryWriter is used for writing binary data to a Stream – Simply the reverse, you can create jpegs, mpegs, wave files if you know the file format (internal structure of bits) • As with the BinaryReader, a BinaryWriter requires a Stream to work on: //Create a new file and pass it to a Binary Writer Stream OutStream = new FileStream(“test_out.txt”,FileMode.Create); BinaryWriter Writer = new BinaryWriter(OutStream); //Write an array of bytes to the file Writer.Write(Buffer, 0, nBytes); //Close the file stream OutStream.Close(); 443 ENEL712-Embedded Systems Design File Dialog Boxes • Leveraging off the .NET Framework allows us access to standard Windows dialog boxes – This saves us a lot of time – we don’t have to develop them! – Two of the most common are the open and save file dialog boxes: 444 ENEL712-Embedded Systems Design OpenFileDialog • The OpenFileDialog is available from the Toolbox in the Visual Studio Designer – As discussed, it is a nonvisual element – This means it is placed in the status area • By default the OpenFileDialog won’t do anything, it won’t even be displayed! – You have to program it to do what you want 445 ENEL712-Embedded Systems Design OpenFileDialog Example • Hints: – Always check the user clicked OK when using a dialog box! – Use ShowDialog() to avoid the user missing / ignoring the dialog box //Open the dialog box and check the user clicked ok if(openFileDialog1.ShowDialog(this) == DialogResult.OK) { //If the user clicked ok, display the filename Console.WriteLine(openFileDialog1.FileName); //Your code here, e.g. Stream InStream = new FileStream(openFileDialog1.FileName,FileMode.Open); } //Otherwise – do nothing! 446 ENEL712-Embedded Systems Design SaveFileDialog • As with the OpenFileDialog, the SaveFileDialog implements a .NET dialog to allow the user to select a location to save a file – Drag and drop from the Toolbox onto the status area – It also checks for existing files (so we don’t have to!) • However as before, it does not create the file for us – It just provides a means to find a location on the users computer to save a file • You can force the dialog to only allow certain file types to be saved by setting the Filter property of the dialog box: – “MP3 Files|*.mp3” will only allow mp3 files to be saved – The same concept applies to the OpenFileDialog. 447 ENEL712-Embedded Systems Design Directory Methods • Using .NET you can also perform all normal file and directory tasks: FILE DIRECTORY File.Copy() Directory.CreateDirectory() File.Create() Directory.Delete() File.Delete() Directory.Exists() File.Exists() Directory.Move() File.Move() File.Open() File.Replace() • These are especially useful when working with temporary files and folders 448 ENEL712-Embedded Systems Design Other File Operations • There are also plenty of other useful file and directory classes and methods in the System.IO namespace – Here are a few from the Path Class: Class Method System.IO.Path ChangeExtension() System.IO.Path GetExtension() System.IO.Path GetFileName() System.IO.Path GetFullPath() System.IO.Path HasExtension() System.IO.Path IsPathRooted() 449 ENEL712-Embedded Systems Design File Handling + Exception Handling • File handling is a perfect example of when exception handling is very important – Often problems with read only directories, files already in use, unexpected formats, etc – Very important to use try and catch! try { os = new FileStream(outfile, FileMode.Create); } catch { throw new ApplicationException("Cannot access the output file!"); } 450 ENEL712-Embedded Systems Design C# SerialPort Object • The C# SerialPort object makes it easy to use the Serial Port on a PC – Online documentation is very good: • https://msdn.microsoft.com/enus/library/system.io.ports.serialport(v=vs.110).aspx • The SerialPort object can be created programmatically or graphically via the designer – My preference is programmatically – SerialPort sp = new SerialPort(); • By default SerialPort methods are blocking – This means they stop your program executing while they execute – This behaviour can be changed by setting an Event Handler associated with the DataReceived Event. – You can also use timeouts to prevent lock-up 451 Good Resource: http://www.codeproject.com/Articles/678025/Serial-Comms-in-Csharp-for-Beginners ENEL712-Embedded Systems Design SerialPort Example SerialPort sp = new SerialPort(); sp.PortName = “COM6”; //string sp.BaudRate = 38400; //Int32 try { sp.Open(); } catch(Exception ex) { MessageBox.Show(“Error Opening SerialPort! ” + ex.Message); return; } Note use of //Data to Send try-catch! byte[] buffer = {0x00, 0x01, 0x02}; try { sp.Write(buffer,0,2); } catch(Exception ex) { MessageBox.Show(“Error transmitting data: “ + ex.Message); return; } 452 ENEL712-Embedded Systems Design SerialPort Useful Methods • Use the documentation, but these are the main ones: Method Description SerialPort() Default Constructor SerialPort(String,Int32) Constructor specifying COM and Baudrate Open() Open the Serial Port (must be called first) Close() Close the Serial Port IsOpen() Check if the Serial Port is Open GetPortNames Get names of available COM ports [Static] Read(Byte[],Int32,Int32) Read a number of bytes into an array ReadByte() Read a single byte ReadExisting() Reads all available bytes into a string Write(Byte[],Int32,Int32) Write a byte array to the serial port Write(String) Write a string to the serial port 453 ENEL712-Embedded Systems Design SerialPort - Points to Remember • The SerialPort Object may buffer received bytes – This means you may receive only some of the bytes transmitted to the PC the first time you call Read – Use ReadExisting to avoid this problem • Your Program should Keep Sync with the Remote Device – If the remote device sends a byte, the PC will buffer it – Therefore if you don’t need the byte, you must call Read to process it – Otherwise you the next time you read a byte, you will receive the unwanted byte • Watch out for Endianness Problems – – – – http://en.wikipedia.org/wiki/Endianness Intel normally Little-Endian AVR normally Big-Endian Only a problem when sending multi-byte variables 454 Lecture 23 Graphics and Plotting ENEL712-Embedded Systems Design Inserting Images • An easy way to make your GUI more exciting is to add an image, or a few – Remember the user has to stare at your interface the entire time – A grey box (or collection of grey boxes) isn’t always appealing • The PictureBox control allows you to insert a GIF, JPG, BMP or PNG image into your application – You can also customize how it is displayed 456 ENEL712-Embedded Systems Design Custom Graphics • There may be times when you want to draw your own graphics – This can be accomplished using simple drawing commands – Similar concept to the Othello / Reversi / Backgammon game you developed in 1st year • .NET provides many of the required classes and methods to draw lines, circles, squares, etc – They are located within the System.Drawing namespace 457 ENEL712-Embedded Systems Design Panels, Graphics and Pens • In order to draw you require 3 things: • Panel / Form – This is your drawing surface (i.e. canvas) – Typically we use a panel, but you can also use the Form • Graphics Object – This is the class that provides methods for drawing on the panel – As well as drawing individual points, it also allows you to draw shapes – DrawLine, DrawEllipse, DrawCurve, FillPolygon, etc • Pen Object – This is what you draw with! – You choose the line width and colour 458 ENEL712-Embedded Systems Design DrawLine Example • This example draws a line on a panel on a Windows Forms C# Application – Remember, the origin (0,0) of all controls is the top left private void panel1_MouseDown(object sender, MouseEventArgs e) { //Create a graphics object on the panel System.Drawing.Graphics gObj = this.panel1.CreateGraphics(); //Create a pen to draw with Pen bluePen = new Pen(Color.Blue); //Draw the line (0,0) to (100,100) gObj.DrawLine(bluePen, 0, 0, 100, 100); } • When we click on the panel, the line is drawn: 459 ENEL712-Embedded Systems Design The Paint Event • While the previous code appeared to work, if we minimised the window (or moved another window in front of it), the line will disappear! – This is because the line is only drawn when the user clicks on the panel – It is not drawn when the window is ‘painted’ • Each time a window has to be redrawn (i.e. because it was minimized or something covered it), the Paint Event is called – By default this will only create the default graphical representation of each of your controls, not our custom line! – However we can create an event handler for the Paint Event in order to maintain our graphics 460 ENEL712-Embedded Systems Design Paint Event Example • This example is the paint event handler for the same panel private void panel1_Paint(object sender, PaintEventArgs e) { //Get the graphics object passed to us System.Drawing.Graphics gObj = e.Graphics; //Create a pen Pen redPen = new Pen(Color.Red); //Draw the line (0,100) to (100,0) gObj.DrawLine(redPen, 0, 100, 100, 0); } • Note the red line is drawn automatically, the blue line is only drawn when we click on the panel 461 ENEL712-Embedded Systems Design The Pen • The Pen is used to draw lines, as well as the borders of shapes – Other than colour (color), there are a few other useful properties we can set • Width – Specified as the number of pixels (float) – bluePen.Width = 3; • DashStyle – For dotted or dashed lines – bluePen.DashStyle = Drawing2D.DashStyle.Dash; • Transparency – Other than preset colours, you can specify alpha + RGB triplets – Pen bluePen = new Pen(Color.FromArgb(100,0,0,255)); 462 ENEL712-Embedded Systems Design The Brush • The Brush Object defines how shapes are filled – Like the pen its main property is colour • However you can also customize the type of fill using the Style property: – – – – HatchBrush (foreground and background) LinearGradientBrush SolidBrush (default) TextureBrush (uses an image) 463 ENEL712-Embedded Systems Design Drawing Shapes • When drawing shapes there are two types of methods – DrawRectange() - draw the outline of a rectangle – FillRectange() – draw a filled (solid) rectangle • Using the Graphics Object, simply call the required method – DrawRectangle(pen, x, y, width, height) – DrawEllipse(pen, x, y, width, height) – FillRectange(brush, x, y, width, height) • Note the use of a pen when drawing shape outlines, and a brush when drawing a solid shape • All shapes are drawn relative to an origin (x,y), which is the top-left-hand point of the shape – And the size of the shape specified by (width, height) in pixels 464 ENEL712-Embedded Systems Design Drawing Text • Text can also be added to a Graphics object, but requires a Brush and a Font: private void panel1_Paint(object sender, PaintEventArgs e) { Graphics gObj = e.Graphics; //Create a Font Object of 16pt Arial Font myFont = new Font(“Arial”,16); //Create a Green Brush SolidBrush myBrush = new SolidBrush(Color.Green); //Draw “Hello” in green 16pt Arial at (20,30) gObj.DrawString(“Hello”,myFont,myBrush,20,30); } 465 ENEL712-Embedded Systems Design Programming Exercise • Create a new C# Windows Forms Application – Write a function that draws a 3x3 grid on the form – Internal Vertical lines should be red & dashed – Internal Horizontal lines should be blue & dotted – Outside lines should be solid black – You choose the size – Note: Your program should be able to resize easily! 466 ENEL712-Embedded Systems Design Plotting • What we have shown you so far is good for simple graphics – However it becomes tedious for drawing anything complex • A common graphics job is to plot some data – This quickly becomes difficult using lines, rectangles and strings! – .NET provides a nice looking Chart object (under Data) – In previous C++ assignments this was your task: 467 ENEL712-Embedded Systems Design Butterworth Filter Designer 468 ENEL712-Embedded Systems Design Using the .NET Chart Control • Simply drag and drop the Chart control onto your Form • An example plot will be automatically created – The default is a bar chart 469 ENEL712-Embedded Systems Design Customizing the Chart Control • The Chart control contains a number of properties for customizing the look at feel of it • Colours can be changed under the Appearance Group • However all other properties, such as chart type, axes properties and legends and under the Chart Group – Each property is a collection, which opens up a GUI for modifying that collection • For example, use the Series Collection Editor to modify the chart type and data 470 ENEL712-Embedded Systems Design Plotting Using the Chart Control • Each chart has a series collection, which when indexed, you can access the points property, and add new points to the graph. 471 ENEL712-Embedded Systems Design Freeware Plotting Tools • We are not limited to just the controls supplied with .NET – There are plenty of freeware (and commercial) ones available online • A good example is Nplot, a freeware plotting library for .NET – Available from netcontrols.org/nplot • Also Oxyplot, another free version: – http://oxyplot.codeplex.com/ 472 ENEL712-Embedded Systems Design Programming Exercise • Create a new C# Windows Forms Application – Add a .NET Chart Object – Plot the following equation between -1 ≤ x ≤ 1 tan−1 15𝑥 𝑦= sin−1 𝑥 473 Lecture 24 Debugging ENEL712-Embedded Systems Design The Need to Debug • It is almost impossible to write a (typical) program from beginning to end and not have at least one mistake – Typically there will be many! • Some bugs (mistakes) are easy to find – The code editor automatically underlines in red most syntax errors • However runtime errors (those which only occur once the program is run) are often much more difficult to identify 475 ENEL712-Embedded Systems Design Typical Runtime Errors • Runtime errors can generally fall into two categories: – Invalid Data • Divide by zero, cannot parse, no file • These can be caught using a try and catch – Logic Errors • Your program does not run as per the specification! • Fault in your logic, i.e. if / else, incorrect number of iterations, wrong code order • However both of these types of errors can be diagnosed using debugging! 476 ENEL712-Embedded Systems Design Debugging Attitudes… • “Any sufficiently advanced bug is indistinguishable from a feature” • “Sometimes it pays to stay in bed on Monday, rather than spend the rest of the week debugging Monday’s code” • “If it compiles – ship it!” 477 ENEL712-Embedded Systems Design Debugging In Visual Studio • Visual Studio is not just a code writing and compiling tool, it is also a powerful debugging tool – This allows you to observe the runtime behaviour of your program (you can see what’s happening when you’re running it!) • With the debugger you can: – – – – – Break or suspend the execution of your program Step through, line by line, your program Evaluate and edit variables View registers and instructions View memory used by your application 478 ENEL712-Embedded Systems Design Setting Breakpoints • The basic concept behind debugging is setting breakpoints – Simply click in the margin next you want to check to set a breakpoint • Breakpoints break the execution of your program when your program reaches that line – This allows you to inspect variables and control execution! Remember: F5 – Start Debugging Ctrl + F5 – Start Without Debugging 479 ENEL712-Embedded Systems Design Start Debugging (F5) • Press F5 to start your application, ensuring you are building a Debug version • Once your application reaches the breakpoint, it will jump back into Visual Studio – The yellow arrow indicates the current line the program is up to – It has not yet executed this line 480 ENEL712-Embedded Systems Design Inspecting Variables • Once your program has hit the breakpoint, you can use the watch window (bottom left) to inspect the values of variables in your program • The Autos tab takes a guess at the variables of interest to you – You can edit the values here if you want! Checking for Invalid Data! 481 ENEL712-Embedded Systems Design Inspecting Local Variables • Use the Locals tab to view all local variables in the current function scope – This includes passed arguments! • You can always use the Watch window to enter your own variables to check – You can even enter basic expressions to evaluate! 482 ENEL712-Embedded Systems Design Inspecting the Call Stack • It can also be useful to determine how your program reached the current breakpoint – This can be achieved by inspecting the Call Stack • By reading down the list, we can see function that was called in order to arrive at our breakpoint 483 ENEL712-Embedded Systems Design Stepping Through Your Program • One of the most useful features of the debugger is the ability to ‘step’ through your program • Once your program has hit a breakpoint, you can step, line by line, through your program – This is most often the best way to check for logic errors! – At each line you can also inspect variables that have changed value Checking for Logic Errors! 484 ENEL712-Embedded Systems Design Stepping Controls Continue Restart Step Into Step Out Stop Current Line Step Over • Continue (F5) – Continue running the program until the program finishes, or the next breakpoint is hit • Stop (Shift + F5) – Stop execution of the program • Restart (Ctrl + Shift + F5) – Restart program execution • Current Line – Show the current line to be executed • Step Into (F11) – Step into a function / method on the current line • Step Over (F10, Most Common) – Step over the current line, executing any methods on it • Step Out (Shift + F11) – Step out of the current method, and return to the calling method 485 ENEL712-Embedded Systems Design Conditional Breakpoints • Breakpoints can also be set as conditional – This allows you to specify only under certain conditions will the program break • Simply right click on the breakpoint and click condition – Enter a C# expression to evaluate as the condition 486 ENEL712-Embedded Systems Design Printing Messages at Breakpoints • Instead of (or as well as) breaking program execution at breakpoints, you can print messages to the output window – These can contain the values of current function variables, or thread / process information 487 ENEL712-Embedded Systems Design Printing Debug Messages • Another method of writing to the output window is to use: System.Diagnostics.Debug.WriteLine(“string”); • This allows messages like in the previous slide, but without requiring a breakpoint – Useful for tracking program execution and values! 488 ENEL712-Embedded Systems Design Programming Exercise • Open a program you have written previously – E.g. the Graphics example program – Practice setting conditional breakpoints, and ensure they are hit – Examine the Stack Trace – Try writing Debug messages 489 ENEL712-Embedded Systems Design Vista 490 Appendix A Review of C++ ENEL712-Embedded Systems Design Review of C++ • Everyone has done Engineering Computing (or equivalent) – Therefore this course expects you to know basic programming fundamentals • However this is one lecture for a quick catch up. 492 ENEL712-Embedded Systems Design Data Types • All variables in a C based language require a data type, e.g. : – char x – int y – float z • The data type used is specified by what type of data you want to store in the variable – Integer (whole numbers): bool, char, int, long – Real (decimal point): float, double • Within the above types are different sized variables (number of bits). The more bits, the bigger the number the variable can store. – There are also signed and unsigned variations of integer types. Signed types allow for negative numbers to be stored. 493 ENEL712-Embedded Systems Design Data Types (Continued) • In order to maximise the efficiency of your program, always choose the smallest data type required to store your data – If you need to store whole numbers 0 to 100 use an unsigned char (0 – 255) [8 bits] – If you need to store round numbers -10,000 to 10,000, use a signed short (-32,768 to 32,767) [16 bits] – And so forth • See the following link for a complete list: • http://msdn.microsoft.com/enus/library/s3f49ktz(v=vs.110).aspx 494 ENEL712-Embedded Systems Design Common Operations • Common mathematical operators: – – – – – – Add [+] Subtract [-] Multiply [*] Divide [/] Increment [++] Decrement [--] • More complex mathematical functions require functions: – Math::Pow(x,y) – Math::Sin(x) 495 ENEL712-Embedded Systems Design Keep Data Types Consistent • Common mistake below: int x = 10; double y = 2.0; int b = x/y; //gives a warning • Keep your data types consistent. If you can’t, cast them! int b = x/(int)y; //type cast 496 ENEL712-Embedded Systems Design Program Loops: for int i; Start Condition Stop Condition Iteration Operation for(i = 0; i < 10; i++) { cout << i << endl; //display i } 497 ENEL712-Embedded Systems Design Program Loops: while Start Condition int i = 0; Loop while Condition is True while(i < 10) { cout << i << endl; //display i i++; Loop Control Variable } 498 ENEL712-Embedded Systems Design Conditional Statements: if / else double x = 1.7; if(x > 2) cout else if(x cout else cout << “Greater than 2” << endl; < 1) << “Less than 1” << endl; << “Between 1 and 2” << endl; Remember curly braces {} are only required if the code to execute is more than 1 line. 499 ENEL712-Embedded Systems Design Functions return_type function_name(input_args … ) For example the function below: double cube(double x); Is called cube, accepts one input argument of type double, and returns one argument of type double. Remember all functions in C can only return one argument – however you can use pointers / handles. 500 ENEL712-Embedded Systems Design Cube Function double cube(double x) { double y; //define return variable y = x*x*x; //calculation return y; //return value } • Remember: – – – – You need a function prototype at the top of your file. Function body must be within curly braces. Functions with a return type must include a return statement. Always comment your program! 501 ENEL712-Embedded Systems Design Pointers and Handles (Reference) • Arguments passed to a function are copied, you cannot modify the original variable in the function – However if you pass it as a pointer or handle, you can. – Useful for passing arrays, values you wish to change, or extra outputs Handle: void cube(double &x) Pointer: void cube(double *x) 502 ENEL712-Embedded Systems Design Pointer vs Handle Example void square(double &x) { x = x * x; //direct use of x } void square(double *x) { *x = *x * *x; //dereference x } Multiply Dereference 503 ENEL712-Embedded Systems Design Arrays and Vectors • Important concept in engineering: – Most of our data is in vectors or matrices! int myArray[5]; Data Type of the Array Name of the Array Number of Elements In the Array To set an element of the array: myArray[2] = 3; //0 indexed! 504 ENEL712-Embedded Systems Design Dynamic Memory Allocation • What happens if you don’t know the required size of the array when you write the program? – Use dynamic memory allocation! – Allocates memory for the array at run-time int *myArray; //a new pointer to an int myArray = new int[5]; //get memory for 5 ints delete [] myArray; //after use – delete memory 505 ENEL712-Embedded Systems Design Passing Arrays to a Function • Commonly we want pass arrays to function to operate on them. If they are dynamically created only at runtime we will not know their length… – Solution, pass them as pointers! – However we must also pass the length of the array double sse(double *y, double *yhat, int n) 506 ENEL712-Embedded Systems Design Summary • C++ is a powerful language and will be around for many more years – So don’t think because we teach C# now you can forget it! • I still use C and C++ every week. – It is a valuable tool to create fast algorithms. • But in terms of Windows application development, C# is now the leader. 507 ENEL712-Embedded Systems Design Class Exercise • Create a Win32 C++ Console Application in Visual Studio 2013 • Write a program that can raise the following matrix to the power of n, where n is a user input supplied at the command line: 8 1 6 3 5 7 4 9 2 • The program should then display the resulting matrix at the command line 508