Kĩ thuật lập trình - Chapter 25: Embedded systems programming
Failing how?
In general, we cannot know
In practice, we can assume that some kinds of errors are more common than others
But sometimes a memory bit just decides to change (cosmic ray, silicon fatigue, )
Why?
Power surges/failure
The connector vibrated out of its socket
Falling debris
Falling computer
X-rays
Transient errors are the worst
E.g., only when the temperature exceeds 100° F. and the cabinet door is closed
Errors that occur away from the lab are the worst
E.g., on Mars
36 trang |
Chia sẻ: nguyenlam99 | Lượt xem: 1002 | Lượt tải: 0
Bạn đang xem trước 20 trang tài liệu Kĩ thuật lập trình - Chapter 25: Embedded systems programming, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Chapter 25Embedded systems programmingBjarne Stroustrup www.stroustrup.com/ProgrammingAbstractThis lecture provides a brief overview of what distinguishes embedded systems programming from “ordinary programming.” It then touches upon facilities that become prominent or problems when working “close to the hardware” such as free store use, bit manipulation, and coding standards. Remember: not all computers are little grey boxes hiding under desks in offices.*Stroustrup/Programming Nov'13OverviewEmbedded systemsWhat’s special/differentpredictabilityResource managementmemoryAccess to hardwareAbsolute addressesBits – unsignedCoding standards*Stroustrup/Programming Nov'13Embedded systemsHard real timeResponse must occur before the deadlineSoft real timeResponse should occur before the deadline most of the timeOften there are plenty of resources to handle the common casesBut crises happen and must be handledPredictability is keyCorrectness is even more important than usual“correctness” is not an abstract concept“but I assumed that the hardware worked correctly” is no excuseOver a long time and over a large range of conditions, it simply doesn’t*Stroustrup/Programming Nov'13Embedded systemsComputers used as part of a larger systemThat usually doesn’t look like a computerThat usually controls physical devicesOften reliability is critical“Critical” as in “if the system fails someone might die”Often resources (memory, processor capacity) are limitedOften real-time response is essential*Stroustrup/Programming Nov'13Embedded systemsWhat are we talking about?Assembly line quality monitorsBar code readersBread machinesCamerasCar assembly robotsCell phonesCentrifuge controllersCD playersDisk drive controllers“Smart card” processors*Fuel injector controlsMedical equipment monitorsPDAsPrinter controllersSound systemsRice cookersTelephone switchesWater pump controllersWelding machinesWindmills Wrist watchesStroustrup/Programming Nov'13Do You Need to Know This Stuff ?Computer Engineers – You will build and oversee the building of these systemsAll “close to the hardware” code resembles thisThe concern for correctness and predictability of embedded systems code is simply a more critical form of what we want for all codeElectrical Engineers – You will build and oversee the building of these systems.You have to work with the computer guysYou have to be able to talk to themYou may have to teach themYou may have to take over for themComputer scientists – you’ll know how to do this or only work on web applications (and the like) *Stroustrup/Programming Nov'13PredictabilityC++ operations execute in constant, measurable timeE.g., you can simply measure the time for an add operation or a virtual function call and that’ll be the cost of every such add operation and every virtual function call (pipelining, caching, implicit concurrency makes this somewhat trickier on some modern processors)With the exception of:Free store allocation (new)Exception throwSo throw and new are typically banned in hard real-time applicationsToday, I wouldn’t fly in a plane that used thoseIn 5 years, we’ll have solved the problem for throwEach individual throw is predictable Not just in C++ programsSimilar operations in other languages are similarly avoided*Stroustrup/Programming Nov'13Ideals/aimsGiven the constraintsKeep the highest level of abstractionDon’t write glorified assembler codeRepresent your ideas directly in codeAs always, try to write the clearest, cleanest, most maintainable codeDon’t optimize until you have toPeople far too often optimize prematurelyJohn Bentley’s rules for optimizationFirst law: Don’t do itSecond law (for experts only): Don’t do it yet*Stroustrup/Programming Nov'13Embedded systems programmingYou (usually) have to be much more aware of the resources consumed in embedded systems programming than you have to in “ordinary” programsTimeSpaceCommunication channelsFilesROM (Read-Only Memory)Flash memoryYou must take the time to learn about the way your language features are implemented for a particular platformHardwareOperating systemLibraries *Stroustrup/Programming Nov'13Embedded systems programmingA lot of this kind of programming isLooking at specialized features of an RTOS (Real Time Operating System)Using a “Non-hosted environment” (that’s one way of saying “a language right on top of hardware without an operating system”)Involving (sometimes complex) device driver architecturesDealing directly with hardware device interfacesWe won’t go into details hereThat’s what specific courses and manuals are for*Stroustrup/Programming Nov'13How to live without newWhat’s the problem?C++ code refers directly to memoryOnce allocated, an object cannot be moved (or can it?)Allocation delaysThe effort needed to find a new free chunk of memory of a given size depends on what has already been allocated FragmentationIf you have a “hole” (free space) of size N and you allocate an object of size M where M class Pool {public: Pool(); // make pool of N Ts – construct pools only during startup T* get(); // get a T from the pool; return 0 if no free Ts void free(T* p); // return a T given out by get() to the poolprivate: // keep track of T[N] array (e.g., a list of free objects)};Pool sb_pool;Pool indicator_pool;*Stroustrup/Programming Nov'13Stack example// Note: allocation times completely predictable (and short)// the user has to pre-calculate the maximum number of elements neededtemplate class Stack {public: Stack(); // make an N byte stack – construct stacks only during startup void* get(int N); // allocate n bytes from the stack; return 0 if no free space void free(void* p); // return the last block returned by get() to the stackprivate: // keep track of an array of N bytes (e.g. a top of stack pointer)};Stack my_free_store; // 50K worth of storage to be used as a stackvoid* pv1 = my_free_store.get(256 * sizeof(int)); // allocate array of intsint* pi = static_cast(pv1); // you have to convert memory to objectsvoid* pv2 = my_free_store.get(50);Pump_driver* pdriver = static_cast(pv2);*Stroustrup/Programming Nov'13TemplatesExcellent for embedded systems workNo runtime overhead for inline operationsSometimes performance mattersNo memory used for unused operationsIn embedded systems memory is often critical (limited)*Stroustrup/Programming Nov'13How to live with failing hardwareFailing how?In general, we cannot knowIn practice, we can assume that some kinds of errors are more common than othersBut sometimes a memory bit just decides to change (cosmic ray, silicon fatigue, )Why?Power surges/failureThe connector vibrated out of its socketFalling debrisFalling computerX-raysTransient errors are the worstE.g., only when the temperature exceeds 100° F. and the cabinet door is closedErrors that occur away from the lab are the worstE.g., on Mars*Stroustrup/Programming Nov'13How to live with failing hardwareReplicateIn emergency, use a spareSelf-checkKnow when the program (or hardware) is misbehavingHave a quick way out of misbehaving codeMake systems modularHave some other module, computer, part of the system responsible for serious errorsIn the end, maybe a person i.e., manual override Remember HAL ? Monitor (sub)systemsIn case they can’t/don’t notice problems themselves*Stroustrup/Programming Nov'13Absolute addressesPhysical resources (e.g., control registers for external devices) and their most basic software controls typically exist at specific addresses in a low-level system (e.g., memory-mapped I/O)We have to enter such addresses into our programs and give a type to such dataFor exampleDevice_driver* p = reinterpret_cast(0xffb8);Serial_port_base* Com1 = reinterpret_cast(0x3f8);*Stroustrup/Programming Nov'13Bit manipulation: Unsigned integersHow do you represent a set of bits in C++?unsigned char uc; // 8 bitsunsigned short us; // typically 16 bitsunsigned int ui; // typically 16 bits or 32 bits // (check before using) // many embedded systems have 16-bit intsunsigned long int ul; // typically 32 bits or 64 bitsstd::vector vb(93); // 93 bitstrue/false auto-converts to/from 1/0Use only if you really need more than 32 bitsstd::bitset bs(314); // 314 bitsUse if you really need more than 32 bitsTypically efficient for multiples of sizeof(int)*Stroustrup/Programming Nov'13Bit manipulation& and| inclusive or^ exclusive or> right shift ~ one’s complement*010010110xaa000111100x0f000010100x0a a:a&b:b:000110000x03b>>2:111000010xf0~b:010111110xafa|b:010101010xa5a^b:101001000x54a> (right shift)~ (one's complement)Basically, what the hardware provides right:For examplevoid f(unsigned short val) // assume 16-bit, 2-byte unsigned short integer{ unsigned char right = val & 0xff ; // rightmost (least significant) byte unsigned char left = (val>>8) & 0xff ; // leftmost (most significant) byte bool negative = val & 0x8000 ; // sign bit (if 2’s complement) // }*110010101100110Sign bit111111110xff:8 bits == 1 byte010010val011falsetrueStroustrup/Programming Nov'13Bit manipulationOr |Set a bit (whether or not already set)And &Is a bit set? Select (mask) some bitsFor example:enum Flags { bit4=1 v;// for (int i = 0; i::size_type i = 0; i::iterator p = v.begin(); p!=v.end(); ++p) for (auto p = v.begin(); p!=v.end(); ++p) for (auto i = 0; i rather than to avoid safety problemsOrganizations often try to manage complexity through coding standardsOften they fail and create more complexity than they manage*Stroustrup/Programming Nov'13Coding standardsA good coding standard is better than no standardI wouldn’t start a major (multi-person, multi-year) industrial project without oneA poor coding standard can be worse than no standardC++ coding standards that restrict programming to something like the C subset do harmThey are not uncommonAll coding standards are disliked by programmersEven the good onesAll programmers want to write their code exactly their own wayA good coding standard is prescriptive as well as restrictive“Here is a good way of doing things” as well as“Never do this”A good coding standard gives rationales for its rulesAnd examples*Stroustrup/Programming Nov'13Coding standardsCommon aimsReliabilityPortabilityMaintainabilityTestabilityReusabilityExtensibilityReadability*Stroustrup/Programming Nov'13Some sample rulesNo function shall have more than 200 lines (30 would be even better)that is, 200 non-comment source linesEach new statement starts on a new lineE.g., int a = 7; x = a+7; f(x,9); // violation!No macros shall be used except for source controlusing #ifdef and #ifndefIdentifiers should be given descriptive namesMay contain common abbreviations and acronymsWhen used conventionally, x, y, i, j, etc., are descriptiveUse the number_of_elements style rather than the numberOfElements styleType names and constants start with a capital letterE.g., Device_driver and Buffer_poolIdentifiers shall not differ only by caseE.g., Head and head // violation!*Stroustrup/Programming Nov'13Some more sample rulesIdentifiers in an inner scope should not be identical to identifiers in an outer scopeE.g., int var = 9; { int var = 7; ++var; } // violation: var hides varDeclarations shall be declared in the smallest possible scopeVariables shall be initializedE.g., int var; // violation: var is not initializedCasts should be used only when essentialCode should not depend on precedence rules below the level of arithmetic expressionsE.g., x = a*b+c; // okif( a0) { y += (z > 5) + z ^ sum + k[sum&3]; sum += delta; z += (y > 5) + y ^ sum + k[sum>>11 & 3]; } w[0]=y; w[1]=z;}*Stroustrup/Programming Nov'13TEAvoid decipher( const unsigned long *const v, unsigned long *const w, const unsigned long * const k){ unsigned long y = v[0]; unsigned long z = v[1]; unsigned long sum = 0xC6EF3720; unsigned long delta = 0x9E3779B9; unsigned long n = 32; // sum = delta0) { z -= (y > 5) + y ^ sum + k[sum>>11 & 3]; sum -= delta; y -= (z > 5) + z ^ sum + k[sum&3]; } w[0]=y; w[1]=z;} *Stroustrup/Programming Nov'13
Các file đính kèm theo tài liệu này:
- 25_embedded_0476.ppt