这个状态机很小,只有3个状态,故以此为例分析状态机C语言代码的结构和含义。该类文件不是由开发人员手工编写的,而是由同名.sm文件编译得到,但两者的大体结构相同。.c文件由状态机控制逻辑直接使用,而.sm只是为了方便开发人员描述状态机,学习时可参照阅读,详见sys-get-eattr.sm状态机描述 。
sys-get-eattr.sm文件由“%%”分隔成三部分,而sys-get-eattr.c是正常的C语言代码,自然不能包含此类分隔符,但可以划分成与之对应的三部分。
- 声明部分
除去包含头文件部分,还有
其中第1行~第4行与sys-get-eattr.sm中一样,是由开发人员声明的需要在定义前使用的函数。第6行~第7行是动作函数的声明,由编译器根据状态机描述自动生成,这些函数在下述第2部分会用到,但定义都在第3部分,所以需在这里声明。
第9行~第11行是状态setup_msgpair所需的数据结构,依次是状态结构体、pjump表(本状态机不含此操作,暂不讨论)和转移表。其后省略的当然还有对应于xfer_msgpair和cleanup两个状态的数据结构。它们的具体赋值和含义见下述第2部分。 - 状态机描述部分
这部分仍然仅以状态setup_msgpair为例。
第1行~第4行定义了本状态机,包括名称和起始状态。起始状态就是.sm文件中状态机描述的第一个状态。
第6行~第13行定义了状态setup_msgpair的相关信息,其中.action.func是动作函数,.trtbl是转移表,所赋的值都在第1部分已经声明过了。第15行~第20行定义了转移表,所谓“return_value”实际指动作函数设定的标志值,0对应.sm文件中的“success”,-1对应.sm文件中的“default”。
同理,xfer_msgpair和cleanup两个状态也会定义相应的数据结构。 - 函数定义部分
这部分和.sm文件的函数定义部分完全相同,定义了接口函数、动作函数和其他用户自定义函数。