FreeRtos-智能家居(4)

智能家居-顶层实现
一.顶层整体逻辑
顶层直接与中间层之间进行业务往来,主要的工作就2个。
1).获取温度,亮度等传感器数据
2).下发风扇和灯的控制命令
顶层的了逻辑很简单,根据获取的温度判断风扇的开发,然后下发控制命令。根据亮度下发灯的开关命令。
二.数据结构组织
1.首先我们需要获取温度和亮度等数据,所以我们新建一个数据采集的结构体
typedef struct
        {
                 int   temprature;     //温度
                 int   bright;         //亮度
                 int   reserved[4];    //其它扩展传感器数据
        } busi_sample_stru;
2.然后我们需要把控制风扇和灯的指令存入一个结构体,以便中间层按照指令执行
typedef struct
        {
                 int fan_status;    //风扇状态控制
                 int light_status;  //灯状态控制
                 int reserved[4];   //其它控制
        } busi_switch_stru;
3.建立模块与模块之间通讯用的结构体
typedef struct
        {
                SemaphoreHandle_t sem_req;  //上层模块向下层模块请求数据的信号量
                SemaphoreHandle_t sem_ack;  //下层模块向上层模块应答的信号量
                void *p_shared_mem;         //上下层模块共用的内存块,上面两个结构体就是
                int shared_mem_nbyte;       //共享内存块的字节长度
        } mmc_ctl_stru;

在该项目中,顶层会定义两组结构体:
(1)
busi_sample_stru busi_sample_values;   //存储传感器数据的结构体
busi_switch_stru busi_switch_values;   //存储控制命令的结构体
(2)
mmc_ctl_stru busi_sample_mmc_ctl;     //顶层和中间层之间通讯传感器信息的结构体
mmc_ctl_stru busi_switch_mmc_ctl;     //顶层和中间层之间通讯控制信息的结构体
三.模块之间通讯
1.模块间通讯的结构体初始化
void mmc_ctl_init(char *mmc_name,mmc_ctl_stru *p_mmc,void *psm,int sm_len)
//结构体之间通讯结构体的初始化
{
    p_mmc->p_shared_mem = psm;                //共享内存的指针指向对应的结构体
    p_mmc->shared_mem_nbyte = sm_len;         //共享数据的长度等于指向的结构体的大小
   
    p_mmc->sem_req = xSemaphoreCreateBinary();//新建一个顶层向中间层请求数据的信号量
    p_mmc->sem_ack = xSemaphoreCreateBinary();//新建一个中间层向顶层应答的信号量
    memset(p_mmc->p_shared_mem,p_mmc->shared_mem_nbyte,0);
   
    log_d("sem req&ack is created,shared mem called %s is initialized",mmc_name);
    log_d("sem req&ack value:%08X %08X",p_mmc->sem_req,p_mmc->sem_ack);
    elog_hexdump("req&ack",8,psm,sm_len);
}  

//采样的mmc结构体的共享内存指针指向busi_sample_values
mmc_ctl_init("busi_sample_values",&busi_sample_mmc_ctl,&busi_sample_values,sizeof(busi_sample_values));
//控制的mmc结构体的共享内存指针指向busi_switch_mmc_ctl
mmc_ctl_init("busi_switch_values",&busi_switch_mmc_ctl,&busi_switch_values,sizeof(busi_switch_values));
2.模块间通讯函数
int mmc_ctl_requre(mmc_ctl_stru *p_mmc_ctl,int waittime)
{
xSemaphoreGive(p_mmc_ctl->sem_req); //requst of datablock via sem req
log_d("sem req is gived");
     
log_d("start waiting for sem ack");
if(xSemaphoreTake(p_mmc_ctl->sem_ack,waittime) == pdTRUE) //wait for sem ack success
{
    log_d("shared memory is ready");
    elog_hexdump("shared memory content",16,&p_mmc_ctl->p_shared_mem,p_mmc_ctl->shared_mem_nbyte);  //log for shared memory raw data
    return pdPASS;
}
else return pdFAIL;
}
顶层和中间层通讯其实就两步,1顶层向中间层发送请求,2中间层向顶层应答(在应答前,中间层把信息装填到共享内存块中,顶层读取共享内存块获取需要的数据)。有了这个函数以后,顶层模块只要向中间层发送两次请求,第一次:请求获取温度和亮度等数据   第二次:根据获取到的传感器数据,请求下发控制命令。而中间层在每次收到顶层的请求以后,都会往顶层定义的共享内存块中填入信息,第一次是温度和亮度等数据,第二次是风扇和灯当前的状态
    //请求获取传感器数据
    if(pdPASS == mmc_ctl_requre(&busi_sample_mmc_ctl,MMC_DELAY_TIME)) //requre for sample values
    {
     log_d("sample requre SUCCESS!");  
       
     log_i("temprature : %d , bright : %d , rsvd0 : %d , rsvd1 : %d , rsvd2 : %d , rsvd3 : %d ",    \
                                                                      busi_sample_values.temprature,  \
                                                                      busi_sample_values.bright,      \
                                                                      busi_sample_values.reserved[0], \
                                                                      busi_sample_values.reserved[1], \
                                                                      busi_sample_values.reserved[2], \
                                                                      busi_sample_values.reserved[3]  \
                                                                     );
       
     if(busi_sample_values.bright < BUSI_BRIGHT_DOWN_THRESHOLD) //current bright level is lowwer than down threshold
     {
        busi_switch_values.light_status = CONTROL_LIGHT_OPEN_STATUS;
      log_w("bright level is too low,OPEN THE LIGHT!");
     }
   
     if(busi_sample_values.temprature < BUSI_TEMPRATURE_DOWN_THRESHOLD) //current bright level is lowwer than down threshold
     {
        busi_switch_values.fan_status = CONTROL_FAN_CLOSE_STATUS;
      log_w("temprature is too low,CLOSE THE FAN!");
     }
     
     if(busi_sample_values.temprature > BUSI_TEMPRATURE_UP_THRESHOLD) //current bright level is higher than up threshold
     {
        busi_switch_values.fan_status = CONTROL_FAN_OPEN_STATUS;
      log_w("temprature is too high,OPEN THE FAN!");
     }
     
     //请求下发风扇、灯等设备的控制命令
     
     if(pdPASS == mmc_ctl_requre(&busi_switch_mmc_ctl,MMC_DELAY_TIME)) //requre for switch action and return status
     {
        log_d("switch requre SUCCESS!");
         
      log_i("fan_status : %d , light_status : %d , rsvd0 : %d , rsvd1 : %d , rsvd2 : %d , rsvd3 : %d ",    \
                                                                             busi_switch_values.fan_status,  \
                                                                             busi_switch_values.light_status,\
                                                                             busi_switch_values.reserved[0], \
                                                                             busi_switch_values.reserved[1], \
                                                                             busi_switch_values.reserved[2], \
                                                                             busi_switch_values.reserved[3]  \
                                                                            );
     }
     else log_e("switch requre FAIL!");
     
  }
    else log_e("sample values requre FAIL!");
   
    vTaskDelay(1000);
}
到这里为止,顶层的业务逻辑已经结束。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小吴的嵌入式笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值