3 classic table-driven design methods

Reprinted from | Last bug

Today I would like to share with you 3 table-driven design methods, all of which are very exquisite and worth collecting and savoring.

1

table driven meaning

For the table-driven method, the conventional approach is to define a table. The table is generally an array of structures. The structure contains the queried data and the processing methods corresponding to the data. During use, different processing processes are realized by looking up the table data and then finding the corresponding processing methods.

7f00bc9f66af3da87d4caae1e8d406da.png

From a functional point of view, the table-driven method is very similar to the switch-case query control process. However, the advantage of the table-driven method lies in the separation of data and processing. With a suitable table structure, when engineers expand functions, they only need to add the corresponding table. Only items are needed, and generally there is no need to change the table processing part.

If you simply use switch-case, a large number of case branches will significantly increase the complexity of the program, making it very inconvenient to find, troubleshoot, and maintain.

However, in current table-driven design, most people think that there is only a fixed method of structure array. In fact, there are two other methods that are very commonly used for the organization of table items. They are introduced below.

2

Three table-driven designs

1. Static structure array construction

This method of organizing table items is the first one that everyone comes into contact with when understanding the table-driven method, and it is also the one that has been introduced the most before. The other two table drivers only organize table items more flexibly based on this method.

Table-driven design mainly involves two aspects: 

a. Object data design

b. Object-relational design

The following is a simple menu table driver example, which is also the most commonly used one.

#include <stdio.h>
#include <stdlib.h>

typedef struct  _tag_Menu stMenu; 
struct  _tag_Menu
{
    char * MenuName;
    void (*MenuPrepare)(void);
    int (*MenuMessage)(void);
    void (*MenuBack)(void);
    //下面省略了相关界面相关数据区域 
};

stMenu sMenu[] = {
    {"Main UI",MainUIPrepare,MainUIMessage,MainUIBack},
    {"Sec UI1",SecUI1Prepare,SecUI1Message,SecUI1Back},
    {"Sec UI2",SecUI2Prepare,SecUI2Message,SecUI2Back},
    {"Thd UI1",ThdUI1Prepare,ThdUI1Message,ThdUI1Back},
    {"Thd UI2",ThdUI2Prepare,ThdUI2Message,ThdUI2Back}
   };

int currMenu = 0;
int NextMenu = 0; 

int main(int argc, char *argv[]) {
 
 while(1)
 {
     NextMenu = sMenu[currMenu].MenuMessage();  //界面消息处理 
     if(NextMenu != currMenu) //需要进行界面切换 
     {
       sMenu[currMenu].MenuBack();    //进行界面退出保存 
       sMenu[NextMenu].MenuPrepare(); //进行新界面的初始化准备
       currMenu =  NextMenu;          //更新界面索引 
     }
 }
 return 0;
}

If you need to add a new menu interface in the future, you only need to modify the driver table items, and the process control part will basically not change much.

However, with such a table design, each deletion needs to be moved to the global static structure data table. In order to avoid directly modifying the public parts as much as possible, I will introduce two other methods to you below.

2. Linked list construction

The above array is a continuous static area. However, in order to better increase the flexibility of table construction, here we use non-continuous data structures such as linked lists to organize the table items. The new module only needs to be added during the initialization process. Just a linked list structure.

Each item in the linked list is similar to the previous array item. During use, as long as the linked list is traversed, the corresponding interface can be obtained for corresponding processing.

Of course, linked lists are only one organizational method, and other faster traversal data structures are also suitable.

3. Link building

Friends who have read Linux or uboot source code should have understood this method. This method is also an improvement on the array table. The array table can be regarded as the programmer artificially organizing the table items.

Therefore, in order to minimize human intervention, you only need to encode and mark according to the prescribed format and hand it over to the compiler for organization. The compiler will also provide corresponding marks, such as the start address and end address of the table, so that the control The stream can look up the table based on these addresses and obtain relevant parameters.

The following is the corresponding processing in uboot for your reference:

(1) Add form of cmd entry in each module

6c6dc9d99b7ff2e097ac6b3573b2b252.png

(2) Implementation of U_BOOT_CMD macro

a9626e6fd02fe2fd74e942297f1cac03.png

(3) Implementation of the traversal process of table items

0ea6776d543922245dc6475e521c209c.png

dec267396adf60b97fbefad56a3c01df.png

I’m sharing it here today, I hope this article can bring you something! If you learn something, remember to give it a like before leaving!

------------ END ------------

2af3797333d4cd692179d28eb6b5d7eb.gif

●Column "Embedded Tools"

●Column "Embedded Development"

●Column "Keil Tutorial"

●Embedded column selected tutorials

Follow the public account and reply "Join the group" Join the technical exchange group according to the rules and reply "1024 " See more.

8ba000bf5be461890bf42085d801b4ba.jpeg

e68bfdb74d68a7ad68b8b48036fccffb.png

Click "Read the original text" to view more shares.

Guess you like

Origin blog.csdn.net/ybhuangfugui/article/details/134985000