美文网首页NB-IoT
2019-10-24NB联网的巧妙设计

2019-10-24NB联网的巧妙设计

作者: 林定益想去NASA捡垃圾 | 来源:发表于2019-10-24 14:56 被阅读0次

与通过外部MCU来控制NB模块的方式不同,在NB芯片内部的开发自然是更需要花些心思的,因为必须要配合芯片自身的程序,在保证其不受干扰的情况下才能开发。
这次谈谈最基础也是最关键的联网操作。
如果是用外部MCU的方式,自然简单,仅仅使用AT指令轮询的方式就可满足。
但是,要直接使用芯片的底层接口,则有一番讲究。


typedef enum CFUN_ATTACH
{
    USER_ATTACH_STATUS_INIT = 0,
    USER_ATTACH_STATUS_TRIGGER_CFUN,
    USER_ATTACH_STATUS_TRIGGER_ATTACH,
}USER_ATTACH_STATUS;


uint8 user_cfun_attach = USER_ATTACH_STATUS_INIT;
static osTimerId_t  user_cfun_timer = NULL;

typedef void (*neul_radio_power_state_callback)(uint8 result);

NEUL_RET set_cfun(uint16 cfun, neul_radio_power_state_callback callback)
{
    NEUL_RET cfun_set_result;
    RPC_ERR rpc_return_code;

    rpc_return_code = command_set_ue_cfun(cfun, (uint8 *)&cfun_set_result);

    if(rpc_return_code == RPC_ERR_OK)
    {
        if(cfun_set_result == NEUL_RET_OK)
        {
            cfun_result_callback = callback;
        }

        return cfun_set_result;
    }

    return NEUL_RET_ERROR;
}

static void user_set_service_result_callback(NEUL_RET result)
{
    static uint8 set_service_count = 0;//需要注意这里一定要用静态变量来计数,否则会一直被清零
    if(result == NEUL_RET_OK)
    {
        //next step
        APP_COAP_INFO("attached");
    }
    else
    {
        if(set_service_count <=RETRY)//与set_cfun函数不同,这里的执行方式相对简单,就是在失败的时候再次尝试
        {
            set_service_sta te(RADIO_POWER_ON, user_set_service_result_callback);
            set_service_count++;
        }
    }
}

static void user_cfun_attach_timer(osTimerId_t xTimer)
{
    UNUSED(xTimer);

    switch(user_cfun_attach)
    {
        case USER_ATTACH_STATUS_INIT:
            //定时器创建失败的情况直接退出
            break;
        case USER_ATTACH_STATUS_TRIGGER_CFUN:
            //在cfun开启失败的情况下并且在允许的重复次数之内,再次开启cfun
            user_set_cfun();
            break;
        case USER_ATTACH_STATUS_TRIGGER_ATTACH:
            //开启cfun成功的条件下,进入attach的操作,该函数与set_cfun类似,都可设置回调函数根据结果执行下一步
            if (set_service_state(RADIO_POWER_ON, user_set_service_result_callback) !=  NEUL_RET_OK)
            {
                return;
            }
            break;
        default:
            break;
    }
}

//根据rpc的返回结果rpc_return_code,来处理下一步
static void user_cfun_result_callback(NEUL_RET result)
{
    static uint8 cfun_count = 0;

    if(result == NEUL_RET_OK)
    {
        cfun_count = 0;
        user_cfun_attach = USER_ATTACH_STATUS_TRIGGER_ATTACH;//如果成功开启射频,将标志位设置成即将进行attach

        if (user_cfun_timer == NULL)
        {
            user_cfun_timer = osTimerNew(user_cfun_attach_timer, osTimerOnce, NULL, NULL);//创建定时器计划执行attach和cfun的操作
            if (user_cfun_timer == NULL)
            {
                cfun_count = 0;
                user_cfun_attach = USER_ATTACH_STATUS_INIT;//如果定时器创建失败则将标志位设置成初始化状态,将直接返回
            }
            else
            {
                osTimerStart(user_cfun_timer, (uint32_t)osMs2Tick(USER_CFUN_ATTACH_TIMER));//创建成功则开启计时,这里是100ms
            }
        }
        else
        {
            osTimerStart(user_cfun_timer, (uint32_t)osMs2Tick(USER_CFUN_ATTACH_TIMER));//如果定时器已经存在,就直接开启计时
        }
    }
    else
    {
        if (cfun_count < RETRY)//允许重复3次
        {
            cfun_count++;
            user_cfun_attach = USER_ATTACH_STATUS_TRIGGER_CFUN;//这里是开启射频失败的情况,标志位设置成即将开启CFUN,就是从头再来一遍
            if (user_cfun_timer == NULL)
            {
                user_cfun_timer = osTimerNew(user_cfun_attach_timer, osTimerOnce, NULL, NULL);//这里的定时器操作跟上面一致,只是到了时间根据标志位的设定会再次执行cfun操作
                if (user_cfun_timer == NULL)
                {
                    cfun_count = 0;
                    user_cfun_attach = USER_ATTACH_STATUS_INIT;
                }
                else
                {
                    osTimerStart(user_cfun_timer, (uint32_t)osMs2Tick(USER_CFUN_ATTACH_TIMER));
                }
            }
            else
            {
                osTimerStart(user_cfun_timer, (uint32_t)osMs2Tick(USER_CFUN_ATTACH_TIMER));
            }
        }
        else
        {
            cfun_count = 0;
            user_cfun_attach = USER_ATTACH_STATUS_INIT;
            if (user_cfun_timer != NULL)
            {
                (void) osTimerStop(user_cfun_timer);
            }
        }
    }
}


static void user_set_cfun(void)
{
    uint16 nconfig_value = 0;
    get_nconfig(NEUL_AUTOCONNECT_FUNCTION, &nconfig_value);

    /*if auto config,return*/
    if (nconfig_value == AUTO_SEARCH)
    {
        return ;
    }

    set_cfun(RADIO_POWER_ON, user_cfun_result_callback);//通过此函数开启射频,并且可设置回调函数根据执行结果处理下一步操作
}


相关文章

  • 2019-10-24NB联网的巧妙设计

    与通过外部MCU来控制NB模块的方式不同,在NB芯片内部的开发自然是更需要花些心思的,因为必须要配合芯片自身的程序...

  • 业的巧妙设计

    转夕阳 往往两个有久远记忆的人,他们在第一眼的时候,不一定会立刻认出对方。这与你想象的不一样。大多数人都会总感觉,...

  • 巧妙的弯路设计

    娃寒假刚拿的驾照,现在还是实习司机。按交规,上高速路需要有老司机陪同。 我就是那个悲催的老司机。 娃比我当年强很多...

  • RAII

    前言 在写C++设计模式——单例模式的时候,在写到实例销毁时,设计的GC类是很巧妙的,而这一巧妙的设计就是根据当对...

  • Python:logging 的巧妙设计

    引言 logging 的基本用法网上很多,这里就不介绍了。在引入正文之前,先来看一个需求: 假设需要将某功能封装成...

  • 设计巧妙的飞利浦插座

  • 对抗无家可归的巧妙设计

    对抗无家可归的巧妙设计 从3D打印房屋到平装睡舱,再到社区公寓楼 根据美国住房和城市发展部(U.S. Depart...

  • 高效演讲-巧妙设计

    演讲都有开头,中间和结尾,我们大部分人比较注意开头和结尾,往往中间就草草完事,其实这三部分就像一个三角形,少了那个...

  • 设计模式

    什么是设计模式? 设计模式是一套代码设计「经验的总结」。项目中「合理的」运用设计模式可以「巧妙的解决很多问题」。 ...

  • 德国和日本的设计背后,你不知道的事

    转自:德国严谨理性的设计风格,竟和希特勒有关?以无印良品为代表的日本设计,是如何巧妙利用了设计中的二...

网友评论

    本文标题:2019-10-24NB联网的巧妙设计

    本文链接:https://www.haomeiwen.com/subject/opzrvctx.html