什么是对象?
在面向对象编程中,对象(Object)是指具有某些属性和方法的实体,它是程序的基本构成单位。我们通常使用类(Class)来定义对象的属性和方法。一个类可以看作是对象的模板或蓝图,它定义了对象的特征和行为。当我们创建一个对象时,实际上是创建了一个类的实例,它拥有类定义的属性和方法,我们通常使用对象来表示真实世界中的事物或概念,例如人、汽车、书籍等等。对象具有状态(属性)和行为(方法)两个基本特征,它可以被实例化(创建)并被用于构建程序的不同部分。
以上是对对象的通俗解释,但上面提出了一个重要的点,即面向对象编程。众所周知,C语言并非一门面向对象的开发语言,那么我们又该如何使用C语言完成面向对象开发呢?
其实是有方法的,只不过C语言没有像其他高级语言那样预先定义对象而是需要自己实现,在C语言中,结构体(Struct)是一种用户自定义的数据类型,它允许我们定义自己的数据结构,包含多个不同类型的数据成员。结构体类型由关键字struct定义,后跟结构体名称和数据成员的名称和类型。例如,下面的代码定义了一个名为Person的结构体类型,包含两个整数类型的数据成员age和name:
struct Person {
int age;
bool gender;
char name[20];
};
复制代码struct Person person1;
复制代码定义结构体变量后,我们可以通过赋值来初始化它的数据成员,例如:
person1.age = 20;
person1.bool = male;
strcpy(person1.name, "Alice");
复制代码printf("Person name: %s, age: %d\n", [person1.name](http://person1.name), person1.age);
复制代码在C语言中,结构体类型还支持多重继承(struct和类),结构体和指针,结构体指针和函数等多种用法。结构体在C语言中是一种非常强大的数据类型,可以方便地表示和操作复杂的数据结构。所以我们也可以将产品功能通过结构体的方式进行抽象定义。
创建对象
假设我们的产品是一款IO类控制设备,那么我们所需要设计的主要功能则主要是IO的控制与检测,将上述需求进行归类,其所有的功能都可以归类到IO的操作上来,那么我们就可以此为基础进行扩展,提炼出其中公共的部分。
#define MAX_PIN_ITEM 10
struct Object_pin{
bool mode;
bool state;
uint32_t pin;
void* port;
};
struct io_funt
{
void (*gpio_set)(void* port, uint32_t pin);
void (*gpio_reset)(void* port, uint32_t pin);
bool (*gpio_read)(void* port, uint32_t pin);
};
struct Object_IO
{
struct Object_pin io_list[MAX_PIN_ITEM];
struct io_funt IO_FUN;
void (*exetuct_fun)(struct Object_pin* pin);
void (*gpio_init)(struct Object_pin* pin);
};
struct Object_IO SYS_IO;
void test_exetuct_fun(struct Object_pin* pin)
{
if(pin->mode)
{
if(pin->state)
{
SYS_IO.IO_FUN.gpio_set(pin->port,pin->pin);
}
else
{
SYS_IO.IO_FUN.gpio_reset(pin->port,pin->pin);
}
}
else
{
pin->state = SYS_IO.IO_FUN.gpio_read(pin->port,pin->pin);
}
}
void your_gpio_set(void* port, uint32_t pin);
void your_gpio_reset(void* port, uint32_t pin);
bool your_gpio_read(void* port, uint32_t pin);
void your_sys_gpio_init_function(struct Object_pin* pin);
void system_io_init(void)
{
SYS_IO.IO_FUN.gpio_set = your_gpio_set;
SYS_IO.IO_FUN.gpio_reset = your_gpio_reset;
SYS_IO.IO_FUN.gpio_read = your_gpio_read;
SYS_IO.gpio_init = your_sys_gpio_init_function;
SYS_IO.exetuct_fun = test_exetuct_fun;
for(uint8_t ii = 0; ii < sizeof(SYS_IO.io_list)/sizeof(SYS_IO.io_list[0]); ii++)
{
SYS_IO.gpio_init(&SYS_IO.io_list[ii]);
}
}
void system_io_handler(void)
{
for(uint8_t ii = 0; ii < sizeof(SYS_IO.io_list)/sizeof(SYS_IO.io_list[0]); ii++)
{
SYS_IO.exetuct_fun(&SYS_IO.io_list[ii]);
}
}
复制代码struct Object_pin{
bool mode;
bool state;
uint8_t pin;
uint8_t port;
};
struct Object_IO
{
uint8_t li_cnt;
struct Object_pin *io_list;
struct io_funt IO_FUN;
void (*exetuct_fun)(struct Object_pin* pin);
void (*gpio_init)(struct Object_pin* pin);
};
struct Object_IO SYS_IO;
复制代码配置文件
根据结构体中的io_list对象类型可得知,该指针指向struct Object_pin类型的地址,所以我们仅需要根据Object_pin结构体类型来创建对应的结构体列表即可,首先查看struct Object_pin的结构体成员类型,发现可以将其抽象为键值对的方式进行存储,这样即可选择json格式对配置进行标识,通过json格式能够轻松的标识Object_pin对象的内容,同时json提供了数组类型可以明确表达多个对象,可以选择将文件存储在设备自身存储空间或外部空间中,使用时将文件加载到内存中进行解析。
[{
"mode" : 1,
"state": 0,
"pin" : 0,
"port" : 0
},
{
"mode" : 1,
"state": 0,
"pin" : 1,
"port" : 0
},{
"mode" : 0,
"state": 0,
"pin" : 0,
"port" : 1
},
{
"mode" : 0,
"state": 0,
"pin" : 1,
"port" : 1
}]
复制代码配置文件确定选用json格式后能够选择的解析库就很多了,可以选择著名的cjson解析库或其他解析库也可以自己编写相应的解析库。此处我们选择自有软件库完成解析任务,主要用到的接口为
jsonObj* jsonParse(char* str);
int getJsonObjInteger(jsonObj* obj, const char* key);
导入软件库后创建jsonObj类型的变量用于存储解析后的成员变量 _root,使用jsonParse函数对整个json格式字符串进行解析,并将其存储在_root变量中,使用getJsonObjInteger函数从_root变量中获取我们想要的成员即可。通过对解析后的变量进行存储并赋值给SYS_IO中的io_list指针,同时将解析到的数量赋予SYS_IO中的li_cnt成员用以标记当前指针地址中所存储的对象数量,通过以上方式即完成了动态的加载IO配置。结语
本文介绍了一种基于对象的软硬件可完全分离的软件设计方法,以解决嵌入式软件开发中的一些问题。该方法将系统中的各个模块抽象成对象,并通过对象的实例化来动态改变程序配置。文章详细解释了对象的概念和定义,以及如何使用C语言进行面向对象编程。另外,文章还介绍了系统中IO操作的功能抽象和定义,并提出了一种动态加载IO配置的方法,通过配置文件和解析器实现了IO的灵活切换。该方法可以减少嵌入式软件开发中的固件问题带来的开支,提高产品的灵活性和可维护性。文章最后给出了相关代码示例和配置文件的格式。
特点
(1)软硬件独立
·软件设计独立于硬件。
·可以更换硬件而不需要重新设计软件。
(2)高度可维护
·独立的软硬件设计使得软件维护变得更加容易。
·可以根据硬件更新进行软件升级而不影响现有的软件系统。
(3)提高生产效率
·可以通过可维护的软件设计方法来降低软件开发成本。
·通过可软硬件完全分离的设计方法,可以大大提高软件生产效率。
设计方法
(1)基于对象的设计方法
·将系统中的各个模块抽象成对象,以实现对系统的可维护性和可扩展性。
·基于面向对象的设计原则,使得软件设计更加模块化、可复用、可扩展。
(2)硬件设计
·根据系统需求,进行硬件的选择和设计。
·确保硬件的性能、功能和接口与软件设计要求相匹配。
·保证硬件的可扩展性,以适应未来系统需求的变化。