篆体字网 > 知识库

embedded systems

来源:篆体字网 2023-12-26 14:52:03 作者:篆字君

STL Design PatternsTerminal Manager DocumentationRouting Table DocumentationSTL Design Patterns Source CodeStandard Template Library (STL) has been a part of C++ for a very long timebut many people who have embraced C++ still hesitate in using STL in theirprojects. There is a feeling that STL is difficult and hard to learn. Nothingcould be further from truth. STL is simple to use, debugged and efficient code.STL can reduce the amount on mundane repetitive code that takes up so muchof project time.In this series of articles we will consider some real life design patterns from Embeddedand Real-time systems and develop them using STL. These examples will illustratehow easy it is to implement complex design patterns with very little coding.mapOur examples in this article focus on the STL map. Map allows you to storedata so that it can be quickly accessed via a key. For example consider a phonenumber of circuit mapping in a switching system. The phone numbers have such awide range that an array cannot be defined to provide a quick access from thephone number to the circuit. Searching through all entries is not an option asit would be too expensive. Map addresses this problem by providing aquick access mechanism. This mechanism is implemented using red-black trees.Fortunately using map does not require understanding its internal operations.The following examples show two embedded system patterns implemented using maps:Terminal ManagerRouting TableTerminal Manager exemplifies a typical design pattern seen in embeddedsystems. Here a collection of terminals is being managed by the TerminalManager. Management involves routing messages, creating and deleting terminals.(We more details about this design pattern refer toManagerDesign Pattern).The Terminal Manager implements the following methods:Add_Terminal: Create and add a new terminalRemove_Terminal: Remove and delete a terminalFind_Terminal: Find a terminal from its terminal_IdHandle_Message: Route the received message to the Terminal objectTerminal Manager00009 #include// Header file include for map 00010 using namespace std;// STL containers are defined in std namespace 00011 00012 00013 class Terminal_Message 00014 { 00015 public: 00016 int Get_Terminal_Id() const; 00017 }; 00018 00022 00024 { 00025 public: 00026 00030 00031Terminal(int terminal_Id, int type); 00032 00035 voidHandle_Message(const Terminal_Message *pMsg); 00036 00039 intGet_Terminal_Id() const; 00040 }; 00041 00045 00047 {00051 typedef mapTerminal_Map; 0005200055Terminal_Mapm_terminal_Map; 00056 00057 public: 00058 00059 enum Status {FAILURE, SUCCESS}; 00060 0007400075 StatusAdd_Terminal(int terminal_Id, int type) 00076 { 00077 Status status; 00078 00079 // Check if the terminal is already present in the map. count() 00080 // returns the total number of entries that are keyed by terminal_Id 00081 if(m_terminal_Map.count(terminal_Id)==0) 00082 { 00083 // count() returned zero, so no entries are present in the map 00084Terminal *pTerm=newTerminal(terminal_Id, type); 00085 00086 // Since map overloads the array operator [ ], it gives 00087 // the illusion of indexing into an array. The following 00088 // line makes an entry into the map 00089m_terminal_Map[terminal_Id]=pTerm; 00090 00091 status=SUCCESS; 00092 } 00093 else 00094 { 00095 // count() returned a non zero value, so the terminal is already 00096 // present. 00097 status=FAILURE; 00098 } 00099 00100 return status; 00101 } 00102 0011600117 StatusRemove_Terminal(int terminal_Id) 00118 { 00119 Status status; 00120 // Check if the terminal is present 00121 if (m_terminal_Map.count(terminal_Id)==1) 00122 { 00123 // Save the pointer that is being deleted from the map 00124Terminal *pTerm=m_terminal_Map[terminal_Id]; 00125 00126 // Erase the entry from the map. This just frees up the memory for 00127 // the pointer. The actual object is freed up using delete 00128 m_terminal_Map.erase(terminal_Id); 00129 delete pTerm; 00130 00131 status=SUCCESS; 00132 } 00133 else 00134 { 00135 status=FAILURE; 00136 } 00137 00138 return status; 00139 } 00140 0014700148Terminal *Find_Terminal(int terminal_Id) 00149 { 00150Terminal *pTerm; 00151 if (m_terminal_Map.count(terminal_Id)==1) 00152 { 00153 pTerm=m_terminal_Map[terminal_Id]; 00154 } 00155 else 00156 { 00157 pTerm=NULL; 00158 } 00159 00160 return pTerm; 00161 } 00162 0016800169 voidHandle_Message(const Terminal_Message *pMsg) 00170 { 00171 int terminal_Id=pMsg->Get_Terminal_Id(); 00172 00173Terminal *pTerm; 00174 00175 pTerm=Find_Terminal(terminal_Id); 00176 00177 if (pTerm) 00178 { 00179 pTerm->Handle_Message(pMsg); 00180 } 00181 } 00182 };Routing Table is another pattern that can easily be implemented using map. Inthis routing table, a mapping is maintained from the Node Id to the Link Id.Each routing table entry is specified as a pair of Node Id and Link Id. Given aNode Id, the Routing Table returns the Link Id. We can write pretty much thesame code as the previous example to implement it, but we will take a different route toimplement the same functionality. This time we will use another feature of STL,the iterator.Think of iterators as pointers on steroids. Iterators are special typesdefined by the map that give the appearance of a pointer. Iterators allow youto iterate through the complete data structure. For example the iteratorin a map allows you to iterate through the complete map. The iterator points toa structure containing the key (marked as first) and the actual value stored inthe as second. If this sounds confusing, the following example ofthe Routing Table pattern should clarify things.The Routing Table implements the following methods:Print: Prints out all the entries in the routing table.Add_Routing_Entry: Adds a new entry into the routing tableRemove_Routing_Entry: Removes an entry from the routing tableRoute: Provides the Node Id to Link Id mappingRouting Table00007 00008 #include// Header file include for map 00009 using namespace std; // STL containers are defined in std namespace 00010 00011 typedef int Node_Id; 00012 typedef int Link_Id; 00013 00014 #define INVALID_LINK_ID (-1) 00015 0002700028 classRouting_Table 00029 {00041 typedef mapRouting_Map; 0004200045Routing_Mapm_routing_Map; 00046 00047 public: 00048 enum Status {FAILURE, SUCCESS}; 00049 0006200063 voidPrint() 00064 { 00065 // STL defines a nested type iterator. Here we have declared an instance 00066 // of this nested type. 00067 Routing_Map::iterator it; 00068 00069 // Iterator it "points" to a structure defined as: 00070 // struct Pair 00071 // { 00072 // Node_Id first; 00073 // Link_Id second; 00074 // }; 00075 00076 // map supports predefined begin() and end() markers. begin() "points" 00077 // to the first entry in the map. end() points BEYOND the last entry 00078 // in the map (i.e. the last entry is the entry just before end() 00079 00080 // STL provides pointer like symantics to iterators, thus it++ moves 00081 // the iterator to the next entry in the map. 00082 00083 for (it=m_routing_Map.begin(); it !=m_routing_Map.end(); it++) 00084 { 00085 printf ("Node_Id=%d, Link_Id=%d", it->first, it->second); 00086 } 00087 } 00088 0009800099 StatusAdd_Routing_Entry(Node_Id node_Id, Link_Id link_Id) 00100 { 00101 Status status; 00102 00103 // First check if the entry already exists 00104 if (m_routing_Map.find(node_Id) !=m_routing_Map.end()) 00105 { 00106 // Iterator returns a value other than end, thus this 00107 // is a duplicate addition, return failure 00108 status=FAILURE; 00109 } 00110 else 00111 { 00112 // The end iterator was returned, signifying that 00113 // no entry currently exists, so a new one can be added. 00114m_routing_Map[node_Id]=link_Id; 00115 00116 status=SUCCESS; 00117 } 00118 } 00119 0012600127 StatusRemove_Routing_Entry(Node_Id node_Id) 00128 { 00129 Status status; 00130 // Check if the terminal is present 00131 if (m_routing_Map.find(node_Id) !=m_routing_Map.end()) 00132 { 00133 // Erase the entry from the map. 00134m_routing_Map.erase(node_Id); 00135 status=SUCCESS; 00136 } 00137 else 00138 { 00139 status=FAILURE; 00140 } 00141 00142 return status; 00143 } 00144 0015200153 Link_IdRoute(Node_Id node_Id) 00154 { 00155 Link_Id link_Id=INVALID_LINK_ID; 00156 // Check if the route entry is present 00157 if (m_routing_Map.find(node_Id) !=m_routing_Map.end()) 00158 { 00159 link_Id=m_routing_Map[node_Id]; 00160 } 00161 return link_Id; 00162 } 00163 };Explore More ...Terminal Manager DocumentationRouting Table DocumentationSTL Design Patterns Source Code

上一篇:glibc

下一篇:ibm g40

相关阅读