最近玩了一下nordic
我最近比较虚,新番又很少,玩个王者用李白买红叉快电刀打推进各种赢还经常被人举报,要不是我偷塔他们能赢?这是个推塔的游戏好不好
最近玩了一下nordic , 我随便bb。
刚开车的人一般都是选开发板的,淘宝上买一个,资源有的是,带资料,小公司开发几个蓝牙产品没有问题,震动棒之类的。。哟哟
我发现可以一开始就去自己打板,PACK和各种工具都是开源的,github上面都有很多工具,
https://github.com/NordicSemiconductor/Android-nRF-Connect 工具源码 测试可以用
http://www.nordicsemi.com/eng/content/search?SearchText=Master%20Control%20Panel&filter[]=contentclass_id:54&activeFacets[class:Content%20type]=Resource
APK下载
下载了就安装到自己的手机上,可以先做测试用
2,然后我想说一下分区
这个跟工具有很大的关系,官方的开发工具是keil , 下载安装NordicSemiconductor的 PACK ,库有好几个的,
尼玛市面上卖的一共有这几块芯片,nRF51422_xxAC用的比较多,比如NRF51822 256K ROOM 32K RAM 不要选错了,选错了跑不动的 比了AA 或者AB 都是不一样的芯片
这个就是分区,首先运行BOOTLOADER 然后再运行到APP SD分区是Nordic 的固件 就这三个分区,那个FREE是SWAP分区,这个分区是用来安全升级的,类似于A/B system
MBR没什么的,放一下API ,用来调用更新SD 毕竟那是R0区 ,R0 只能是人家R0 去写
一般记住两个地址就可以 0X03C000 和 SD SIZE SD SIZE 看你是用哪个版本的SD 大小不一样 那么烧写 APP的 offset就不一样 需要改一下
18000 是96 K 我用的是S110 28000 = 160 K 对 是 256K 的room RAM选择随意 够运行就可以了 预留可以大一点
3、说一下空中升级
空中升级是BOOTLOADER 去实现的 , 一般有两种方式
1、按键方式
2、APP切换方式
两种方式都是要切换到boot 去直接运行boot
APP切换方式比较方便一点。
什么鬼啊,意思就是说boot 本身就有一个蓝牙设备 跟APP的代码实现差不多 一样是调用 SD固件API的
还有做好的ZIP包千万要注意!不要放到类似百度云这种云端了,会加密运输的,ZIP头部都被改了,APP空中升级会不断弹出的,用QQ传输ZIP包到手机
FREE分区会先放数据,OK的话会搬到 APP 这样如果数据验证不OK 还可以不会连 之前的APP都进不去了
./nrfutil.exe dfu genpkg /c/Users/10167/Desktop/2017.1.1.zip
--application nrf51422_xxac_s130.hex --application-version 0xffffffff
--dev-revision 0xffff --dev-type 0xffff --sd-req 0xfffe
做ZIP包的工具在
http://www.nordicsemi.com/eng/content/search?SearchText=MCP
下载 X64 或者X86 的
MCP工具怎么用网上有说,太罗逼嗦不想说了。源码在github也有
4、说一下example
如果你是AC 的芯片的话,最好选S130的官方实例
bootloader 路径 D:\Keil_v5\ARM\PACK\NordicSemiconductor\nRF_Examples\11.0.0-2.alpha\dfu\bootloader\pca10028\dual_bank_ble_s130\arm5
sofeware device 路径 D:\Keil_v5\ARM\PACK\NordicSemiconductor\nRF_Examples\11.0.0-2.alpha\ble_peripheral\ble_app_hrs\pca10028\s130_with_dfu\arm5\RTE\nRF_SoftDevice\nRF51422_xxAC
这个编译可以OK的,AC的芯片也不会有什么异常
不过需要改一下BOOTLOADER
-uint8_t m_boot_settings[CODE_PAGE_SIZE] __attribute__((at(BOOTLOADER_SETTINGS_ADDRESS))) __attribute__((used)); /**< This variable reserves a codepage for bootloader specific settings, to ensure the compiler doesn't locate any code or variables at his location. */
+uint8_t m_boot_settings[CODE_PAGE_SIZE] __attribute__((at(BOOTLOADER_SETTINGS_ADDRESS))) __attribute__((used)) = {BANK_VALID_APP}; /**< This variable reserves a codepage for bootloader specific settings, to ensure the compiler doesn't locate
any code or variables at his location. */
将开机地址赋值一下 {BANK_VALID_APP} 就可以了。
5、说一下code 吧
NORDIC的代码就是呵呵哈哈哈,好傻,是我 ,少年
之前,不是说什么RTOS,说的有多牛逼的尼玛,其实是个while(1) ,搞栈列表出来,把函数handle放到struct 上去,包一下,每次运行
列表每行的一个,一行一行运行,就像什么来着,举个名字,叫,矩阵扫描喂狗运行法!人才
喂狗是这样的,每运行完一个handle 会异或一下数值表 ,这个格子在下一次扫描就不会运行了,需要在喂一次狗,需要在这个格子数值表上面再置1
这个我说的是RTOS的,RTOS没什么封装的,妈妈总说我说话很好听,
NORDIC的程序不用去考虑这些啦,很简单的,那些sd_xxxxxx 开头的API都跳不进去的,已经封装在SD固件上面,写写中断函数就可以用了,This is Nordic
??? 什么意思,什么是写一下中断函数就可以用了尼玛
那个中断函数叫:static void ble_evt_dispatch(ble_evt_t * p_ble_evt)
APP那边传过来的 数据到了数据链路层 浮上来的handle就是 ble_evt_t
typedef struct
{
ble_evt_hdr_t header; /**< Event header. */
union
{
ble_common_evt_t common_evt; /**< Common Event, evt_id in BLE_EVT_* series. */
ble_gap_evt_t gap_evt; /**< GAP originated event, evt_id in BLE_GAP_EVT_* series. */
ble_l2cap_evt_t l2cap_evt; /**< L2CAP originated event, evt_id in BLE_L2CAP_EVT* series. */
ble_gattc_evt_t gattc_evt; /**< GATT client originated event, evt_id in BLE_GATTC_EVT* series. */
ble_gatts_evt_t gatts_evt; /**< GATT server originated event, evt_id in BLE_GATTS_EVT* series. */
} evt;
} ble_evt_t;
所有的数据大杂烩都在这里,会进入一个共享中断 ble_evt_dispatch(ble_evt_t * p_ble_evt)
在这个中断里面你可以尽情的去处理ble_evt_t这个handle
void ble_conn_params_on_ble_evt(ble_evt_t * p_ble_evt)
{
switch (p_ble_evt->header.evt_id)
{
case BLE_GAP_EVT_CONNECTED:
on_connect(p_ble_evt);
break;
case BLE_GAP_EVT_DISCONNECTED:
on_disconnect(p_ble_evt);
break;
case BLE_GATTS_EVT_WRITE:
on_write(p_ble_evt);
break;
case BLE_GAP_EVT_CONN_PARAM_UPDATE:
on_conn_params_update(p_ble_evt);
break;
default:
// No implementation needed.
break;
}
}
比如说这个处理函数,on_connect(p_ble_evt) 检查到连接中断然后拿到这个gap结构handle ,有了这个gap handle 你才可以发送特征数据
static void on_connect(ble_nus_t * p_nus, ble_evt_t * p_ble_evt)
{
p_nus->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
}
你也可以在这个
on_connect 标志(连接中断)去开启一个定时器100ms,通过p_ble_evt->evt.gap_evt.conn_handle 可以发送数据,
一般步骤:
services_init ->(sd_ble_gatts_service_add、sd_ble_gatts_characteristic_add)[添加服务] -> ble_evt_dispatch(connect)[等待连接][对比创建
与接收handle] ->打开定时器-> sd_ble_gatts_hvx [发送] -> ble_evt_dispatch (on write)[接收][对比创建与接收handle]
我好虚 我想过吃喝玩乐的日子 想领失业保险过日子成为废柴
6、没了。