简介

本文是mesh小卡light工程的应用修改记录

服务端程序架构

  • 工程初始化
    • 添加头文件路径
    • 指定代码链接空间
  • 驱动
    • 添加驱动文件
    • 驱动初始化处理
  • 应用

    • 入网和退网
    • 设置设备号
    • vendor模型
      • 控制DIDO(ack,通道,值,延时,常闭/常开)
      • 串口透传
    • onoff模型
      • 服务端:读写DIDO
      • 客户端:写DI
    • 串口控制
      • 控制DIDO
      • 通过vendor模型进行透传

        添加头文件路径

  • 根据错误提示添加即可

    指定代码链接空间

    不指定会出现空间不足的故障
    修改“Options for Target ‘Target 1’ -> Linker -> Edit”里面的: :::tips LR_ROM_XIP 0x1101b000 0x01e000 {
    ER_ROM_XIP 0x1101b000 0x01e000 { ; load address = execution address
    .
    .
    .
    oled.o(+RO)
    fs.o(+RO)
    .
    .
    .
    }
    }
    :::

添加驱动文件

  • driver
    • oled.c
    • bsp_button.c
    • bsp_button_tack.c
    • bsp_gpio.c
  • blemesh

    • bsp_btn_demo.c

      驱动初始化处理

      led处理:
      修改gpio为没有用到的引脚

      1. #if (SDK_VER_CHIP == __DEF_CHIP_QFN32__)
      2. #define GPIO_GREEN P7 //重点
      3. #define GPIO_BLUE P31//重点
      4. #define GPIO_RED P14//重点
      5. #else
      6. #define GPIO_GREEN P3
      7. #define GPIO_BLUE P7
      8. #define GPIO_RED P2
      9. #endif

      入网和退网

      入网:
      如果设备还没入网,重新上电就会广播入网请求

      1. if (MS_TRUE == is_prov_req)
      2. {
      3. CONSOLE_OUT("\r\n outline \r\n");
      4. osal_start_timerEx(Demo_TaskID, BTN_DEMO_OUTLINE_EVT,1);
      5. /* Start Provisioning over GATT here */
      6. /**
      7. setup <role:[1 - Device, 2 - Provisioner]> <bearer:[1 - Adv, 2 - GATT]
      8. */
      9. role = PROV_ROLE_DEVICE;
      10. brr = PROV_BRR_GATT|PROV_BRR_ADV; //PROV_BRR_ADV,PROV_BRR_GATT
      11. printf("Bearer type = 0x%02X(Bit0-adv, Bit1-GATT)\r\n", brr);
      12. // UI_prov_brr_handle = brr;
      13. /**
      14. Setting up an Unprovisioned Device over GATT
      15. */
      16. LIGHT_ONLY_RED_ON;
      17. blebrr_prov_started = MS_FALSE;
      18. UI_setup_prov(role, brr);//广播入网请求 //重点
      19. // UI_prov_bind(brr, 0x00);
      20. //ms_access_ps_store(MS_PS_RECORD_SEQ_NUMBER);
      21. CONSOLE_OUT("\r\n Setting up as an Unprovisioned Device\r\n");
      22. }

      退网:
      长按确认键,重置nvs数据并广播入网请求

      1. case BSP_BTN_LPK_TYPE:
      2. CONSOLE_OUT("long press keep ");
      3. if(line_state)
      4. {
      5. key_long_flag = 1;
      6. if(set_state==0)
      7. {
      8. set_state=1;
      9. oled_flash_x();
      10. }
      11. else
      12. {
      13. if(BSP_BTN_INDEX(evt)==0)
      14. {
      15. if(index<2)index++;
      16. else index=0;
      17. oled_flash_x();
      18. }
      19. if(BSP_BTN_INDEX(evt)==2)
      20. {
      21. if(index>0)index--;
      22. else index=2;
      23. oled_flash_x();
      24. }
      25. if(BSP_BTN_INDEX(evt)==1)//重点
      26. {
      27. osal_start_timerEx(Demo_TaskID, BTN_DEMO_OUTLINE_EVT, 1);
      28. out_link();
      29. }
      30. }
      31. osal_start_timerEx(Demo_TaskID, BTN_DEMO_SET_TIMEOUT_EVT, 10*1000);
      32. }
      33. break;
      1. void out_link()
      2. {
      3. UCHAR proxy_state;
      4. UCHAR role, brr;
      5. proxy_state = UI_proxy_state_get();
      6. nvs_reset(NVS_BANK_PERSISTENT);
      7. role = PROV_ROLE_DEVICE;
      8. brr = PROV_BRR_GATT|PROV_BRR_ADV; //PROV_BRR_ADV,PROV_BRR_GATT
      9. blebrr_prov_started = MS_FALSE;
      10. UI_setup_prov(role, brr);
      11. if((ms_iv_index.iv_expire_time!=0)&&(ms_iv_index.iv_expire_time!=0xffffffff))
      12. {
      13. MS_net_start_iv_update_timer(ms_iv_index.iv_update_state,MS_TRUE);
      14. }
      15. }

      设置设备号

      1.短按“+/-”键来增加或减少数字,长按“+/-”键来选这个十百位数
      2.短按“确定”键确定设备号 ```c uint16_t derver_num//设备号,全局变量 void hal_bsp_btn_callback(uint8_t evt) { CONSOLE_OUT(“gpio evt:0x%x “,evt); char str[10]; uint8_t buf[4]; switch(BSP_BTN_TYPE(evt)) { case BSP_BTN_PD_TYPE: CONSOLE_OUT(“press down “); break;

  1. case BSP_BTN_UP_TYPE:
  2. CONSOLE_OUT("press up ");
  3. if(line_state)
  4. {
  5. if(set_state==0)
  6. {
  7. set_state=1;
  8. oled_flash_x();
  9. }
  10. else
  11. {
  12. if(key_long_flag==0)
  13. {
  14. //--------------------------------------------key0------------------------------------//
  15. if(BSP_BTN_INDEX(evt)==0)
  16. {
  17. if(index==0)
  18. {
  19. if((derver_num%10)<9)derver_num+=1;
  20. else derver_num-=9;
  21. }
  22. if(index==1)
  23. {
  24. if((derver_num/10)%10<9)derver_num+=10;
  25. else derver_num-=90;
  26. }
  27. if(index==2)
  28. {
  29. if((derver_num/100)<9)derver_num+=100;
  30. else derver_num-=900;
  31. }
  32. oled_flash_x();
  33. }
  34. //--------------------------------------------key2------------------------------------//
  35. if(BSP_BTN_INDEX(evt)==2)
  36. {
  37. if(index==0)
  38. {
  39. if((derver_num%10)>0)derver_num-=1;
  40. else derver_num+=9;
  41. }
  42. if(index==1)
  43. {
  44. if((derver_num/10)%10>0)derver_num-=10;
  45. else derver_num+=90;
  46. }
  47. if(index==2)
  48. {
  49. if((derver_num/100)>0)derver_num-=100;
  50. else derver_num+=900;
  51. }
  52. oled_flash_x();
  53. }
  54. //--------------------------------------------key1------------------------------------//
  55. if(BSP_BTN_INDEX(evt)==1)
  56. {
  57. set_out();
  58. }
  59. }
  60. else
  61. {
  62. key_long_flag=0;
  63. }
  64. }
  65. osal_start_timerEx(Demo_TaskID, BTN_DEMO_SET_TIMEOUT_EVT, 10*1000);
  66. }
  67. break;
  1. 设备号通过fs文件系统保存到flash里面([【PHY6252-SDK-componentsNVM的使用(存储参数)](https://www.yuque.com/agui-lab/zauxto/udgg4k?view=doc_embed))
  2. ```c
  3. static void set_out()
  4. {
  5. set_state=0;
  6. osal_snv_write(123, 2, &derver_num);
  7. OLED_ShowString(18,24," ",12,0);OLED_ShowString(42,24," ",12,0);OLED_ShowString(30,24," ",12,0);
  8. OLED_Refresh();
  9. }

vendor模型

vendor回调处理:
1.接收到来自客户端发来的MS_ACCESS_VENDORMODEL_NOTIFY_OPCODE数据
2.根据截取的数据段,来判断是否使用DIDO控制(bsp_set_DO,bsp_get_DI)
3.如ack数据段为1,需返回相应的应答数据给客户端

  1. case MS_ACCESS_VENDORMODEL_NOTIFY_OPCODE:
  2. {
  3. UINT8 ack;
  4. uint16 index;
  5. UINT8 ch;
  6. UINT8 val;
  7. uint32 delayms;
  8. UINT8 mode;
  9. data_param = state_params->vendormodel_param;
  10. marker = 0;
  11. MS_UNPACK_LE_1_BYTE(&ack, data_param+marker);
  12. marker += 1;
  13. MS_UNPACK_LE_2_BYTE(&index, data_param+marker);
  14. marker += 2;
  15. MS_UNPACK_LE_1_BYTE(&ch, data_param+marker);
  16. marker += 1;
  17. MS_UNPACK_LE_1_BYTE(&val, data_param+marker);
  18. marker += 1;
  19. MS_UNPACK_LE_4_BYTE(&delayms, data_param+marker);
  20. marker += 4;
  21. MS_UNPACK_LE_1_BYTE(&mode, data_param+marker);
  22. marker += 1;
  23. CONSOLE_OUT("[PDU_Rx] ack:%d,index:%d,ch:%d,val:%d,delayms:%d,mode:%d\r\n",
  24. ack,index,ch,val,delayms,mode);
  25. if(index == derver_num)
  26. {
  27. if((ch==0)||(ch==1))
  28. {
  29. CONSOLE_OUT("OPEN_lock:%d\n",ch);
  30. bsp_set_DO(ch,val,delayms,mode);
  31. }
  32. if(ack)
  33. {
  34. marker = 0;
  35. MS_PACK_LE_1_BYTE_VAL(data_param+marker,++vendor_tid);
  36. marker+=1;
  37. MS_PACK_LE_1_BYTE_VAL(data_param+marker,ack);
  38. marker+=1;
  39. MS_PACK_LE_2_BYTE_VAL(data_param+marker,index);
  40. marker+=2;
  41. MS_PACK_LE_1_BYTE_VAL(data_param+marker,ch);
  42. marker+=1;
  43. if((ch==2)||(ch==3))
  44. {
  45. val = get_DI(ch-1);
  46. CONSOLE_OUT("GET_DI:%d,val:%d\n",ch,val);
  47. }
  48. MS_PACK_LE_1_BYTE_VAL(data_param+marker,val);
  49. marker+=1;
  50. MS_PACK_LE_4_BYTE_VAL(data_param+marker,delayms);
  51. marker+=4;
  52. MS_PACK_LE_1_BYTE_VAL(data_param+marker,mode);
  53. marker+=1;
  54. state_params->vendormodel_param = data_param;
  55. req_type->to_be_acked = 0x01;
  56. CONSOLE_OUT("[PDU_Tx] ack:%d,index:%d,ch:%d,val:%d,delayms:%d,mode:%d\r\n",
  57. ack,index,ch,val,delayms,mode);
  58. }
  59. }
  60. }
  61. break;

控制DO,同时设置DO的常闭常开

  1. void bsp_set_DO(uint8_t ch,uint8_t val,uint32_t delayms,uint8_t mode)
  2. {
  3. if(ch==0)ch_buf = DO1_PIN;
  4. else ch_buf = DO2_PIN;
  5. val_buf = val;
  6. if(delayms)
  7. {
  8. hal_gpio_fast_write(ch_buf,val_buf);
  9. osal_start_timerEx(Demo_TaskID, BTN_DEMO_DO_EVT, delayms);
  10. }
  11. else
  12. {
  13. hal_gpio_fast_write(ch_buf,val);
  14. }
  15. if((ch==0)&&(DO1_mode!=mode))
  16. {
  17. DO1_mode = mode;
  18. osal_snv_write(126, 1, &DO1_mode);
  19. osal_snv_read(126, 1, &DO1_mode);
  20. CONSOLE_OUT("set_do1_mode:%d\n",DO1_mode);
  21. }
  22. else if((ch==1)&&(DO2_mode!=mode))
  23. {
  24. DO2_mode = mode;
  25. osal_snv_write(127, 1, &DO2_mode);
  26. osal_snv_read(127, 1, &DO2_mode);
  27. CONSOLE_OUT("set_do2_mode:%d\n",DO2_mode);
  28. }
  29. }

获取DI

  1. bool get_DI(uint8 di)
  2. {
  3. if(di==1)
  4. {
  5. return hal_gpio_read(DI1_PIN);
  6. }
  7. else
  8. {
  9. return hal_gpio_read(DI2_PIN);
  10. }
  11. return 0;
  12. }