低耦合高内聚的MCU实用软件框架
时间:2021-08-19 15:53:48
[导读]不知道大家有没有听过软件设计中的低耦合,高内聚的两个原则。 具体是什么意思呢? 在一个项目中:每个模块之间相联系越紧密,则耦合性越高;这样你改动其中一个模块,其他模块也需要一起改动,换言之:牵一发而动全身。一个模块内部各个元素之间的联系的紧密程度,如果各个元素(语句、程序段)之间...
不知道大家有没有听过软件设计中的低耦合,高内聚的两个原则。
具体是什么意思呢? 在一个项目中:每个模块之间相联系越紧密,则耦合性越高;这样你改动其中一个模块,其他模块也需要一起改动,换言之:牵一发而动全身。
一个模块内部各个元素之间的联系的紧密程度,如果各个元素(语句、程序段)之间的联系程度越高,则内聚性越高,也就是高内聚。如果一个程序的逻辑处理部分,分散到好几个文件中,那么每次改动,就会改动好几个文件,这就是高耦合。高耦合,低内聚
低耦合,高内聚
现在的软件结构设计,都会要求“低耦合,高内聚”,来保证软件的高质量,提高软件的可维护性。下面是一个低耦合高内聚的一种无OS的MCU实用软件框架。包括任务轮询管理,命令管理器、低功耗管理、环形缓冲区等实用模块。系统中广泛利用自定义段技术减少各个模块间的耦合关系,大大提供程序的可维护性。
MCU:STM32F401RET6
IDE:IAR 7.4或者Keil MDK 4.72A
具体是什么意思呢? 在一个项目中:每个模块之间相联系越紧密,则耦合性越高;这样你改动其中一个模块,其他模块也需要一起改动,换言之:牵一发而动全身。
一个模块内部各个元素之间的联系的紧密程度,如果各个元素(语句、程序段)之间的联系程度越高,则内聚性越高,也就是高内聚。如果一个程序的逻辑处理部分,分散到好几个文件中,那么每次改动,就会改动好几个文件,这就是高耦合。高耦合,低内聚
低耦合,高内聚
现在的软件结构设计,都会要求“低耦合,高内聚”,来保证软件的高质量,提高软件的可维护性。下面是一个低耦合高内聚的一种无OS的MCU实用软件框架。包括任务轮询管理,命令管理器、低功耗管理、环形缓冲区等实用模块。系统中广泛利用自定义段技术减少各个模块间的耦合关系,大大提供程序的可维护性。
主要功能
- 支持模块自动化管理,并提供不同优先等级初始化声明接口。
- 支持任务轮询管理,通过简单的宏声明即可实现,不需要复杂的声明调用。
- 支持低功耗管理,休眠与唤醒通知。
- 支持命令行解析,命令注册与执行。
- blink设备支持,统一管理LED、震动马达、蜂鸣器
使用说明
完整的代码可以参考工程文件,系统开发平台如下:MCU:STM32F401RET6
IDE:IAR 7.4或者Keil MDK 4.72A
任务初始化及任务轮询管理
使用此模块前需要系统提供滴答定时器,用于驱动任务轮询作业。(参考platform.c)//定时器中断(提供系统滴答)
void SysTick_Handler(void)
{
systick_increase(SYS_TICK_INTERVAL); //增加系统节拍
}
注册初始化入口及任务(参考自key_task.c)static void key_init(void)
{
/*do something*/
}
static void key_scan(void)
{
/*do something*/
}
module_init("key", key_init); //注册按键初始化接口
driver_register("key", key_scan, 20); //注册按键任务(20ms轮询1次)
命令管理器(cli)
适用于在线调试、参数配置等(参考使用cli_task.c),用户可以通过串口输出命令行控制设备行为、查询设备状态等功能。命令格式
cli支持的命令行格式如下: < param1> < param2> < paramn> < \r\n > ,< param1>, < param2>, < paramn>, < \r\n >
每行命令包含一个命令名称 命令参数(可选),命令名称及参数可以通过空格或者','进行分隔。系统默认命令
cli系统自带了2条默认命令,分别是"?"与"help"命令,输入他们可以列出当前系统包含的命令列表,如下所示:? - alias for 'help'
help - list all command.
pm - Low power control command
reset - reset system
sysinfo - show system infomation.
适配命令管理器
完整的例子可以参考cli_task.cstatic cli_obj_t cli; /*命令管理器对象 */
/*
* @brief 命令行任务初始化
* @return none
*/
static void cli_task_init(void)
{
cli_port_t p = {tty.write, tty.read}; /*读写接口 */
cli_init( 





