Optimization method of command code processing based on function matrix

Keywords: Programming C

switch optimization method based on function matrix

Definition of command code

During the development of c language, the following situations are often encountered (such as command code mechanism of modem bus protocol):

#define PFUN_REQ_CB_ROW 10 //Rows of request matrix
#define PFUN_REQ_CB_COL 11 //Columns of the request matrix

typedef void (*PFUN_REQ_CALLBACK)(u8 *data,u16 dataLen,u8 newCtl);//Send out

//Indicates not implemented
void reqnone(u8 *data,u16 dataLen,u8 newCtl)
{
	printf("Request not implemented!");
}

const static PFUN_REQ_CALLBACK REQ_CB_Matrix[PFUN_REQ_CB_ROW][PFUN_REQ_CB_COL] PROGMEM=
{
	//Column 0
	//COLUMN0,COLUMN1,COLUMN2,COLUMN3,COLUMN4,COLUMN5,COLUMN6,COLUMN7,COLUMN8,COLUMN9,COLUMNA
	{reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone},//ROW0 row 1
	{reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,req0x19,req0x1A},//ROW1 row 2
	{reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone},//ROW2
	{reqnone,reqnone,reqnone,reqnone,req0x34,req0x35,req0x36,req0x37,req0x38,reqnone,reqnone},//ROW3
	{reqnone,reqnone,reqnone,reqnone,reqnone,req0x45,reqnone,reqnone,reqnone,reqnone,reqnone},//ROW4
	{reqnone,req0x51,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,req0x5A},//ROW5
	{reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone},//ROW6
	{reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone},//ROW7
	{reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone},//ROW8
	{reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone,reqnone}//ROW9
};
void Bus_ReqHandle(u8 requestCode,u8 *data,u16 dataLen,u8 newCtl)
{
	u8 row,column;
	PFUN_REQ_CALLBACK pFun;
	
	row = requestCode>>4;//That's ok
	column = requestCode&0x0f;//column
	
	//Check boundaries
	if(row >= PFUN_REQ_CB_ROW || column >= PFUN_REQ_CB_COL)
	{
		reqnone(data,dataLen,newCtl);
		return ;
	}
	//call
	pFun=pgm_read_ptr_near(&REQ_CB_Matrix[row][column]);
	pFun(data,dataLen,newCtl);
}

Advantage

Compared with switch, intuitive,
Efficient: when the command code is discontinuous, the switch needs to compare several times to find the callback function corresponding to the command code, and the search time of this optimization method is constant.

expectation

In this case, the command code is 8-bit, and the command code is row and column, so it should be encoded in one byte (command code). If the command code does not know a byte, it can be expanded.

proposal

When running on an embedded device:
1. Store the matrix in ram: higher efficiency (depending on the hardware platform).
2. Since the matrix does not need to be changed (constant) at run time, the matrix can be stored in ROM (RAM is more valuable than ROM), which can save RAM (sizeof (callback function pointer)) * number of function matrix elements).

Posted by bsfischer on Mon, 21 Oct 2019 15:17:05 -0700