NCS初探--基于nRF5340的双核通信

接上一章:NCS初探--基于nrf5340的双核测试

此次使用NCS自带的samples:entropy_nrf53,这个例子分为两部分,一部分是应用核代码,一部分是网络核代码,两部分代码完全分开,打开工程时,应用核代码选择cpuapp,网络核代码选择cpunet:

 此工程在网络核上使用了RNG(随机数发生器,只能在网络核上使用),然后应用核通过RPC(Remote Procedure Call 远程过程调用)去获取网络核上的数据,相当于是一个应用核和网络核数据通信的例子。

基本流程为:

1.建立一个通信组,注意此通信组在应用核和网络核都要建立,且要参数一样。

2.应用核和网络核通过互相向通信组里发送和捕捉命令和事件完成通信。在这个例子里,应用核发送命令ID为1、2、3的命令和事件ID为1的事件给网络核,网络核捕捉到这些命令或事件会发送命令ID为4的命令或事件ID为2的事件给应用核。

两个核之间所要传递的数据就夹杂在命令或者事件里,其中命令和事件的区别是:

命令需要响应,而事件不需要。

基于这些了解,我们看一下代码。本章不涉及底层代码实现原理,只是介绍库的使用方法!

网络核与应用核对应代码

打开网络核main.c会发现里面除了一句打印什么都没有,所有细节都在entropy_ser.c里:

首先在文件最下面有整个初始化的入口,细节不再展开,大致流程为把rpc的初始化函数注册在了某个段内,该段会在OS初始化时,循环加载里面的函数,达到自动初始化的目的,加载时机由POST_KERNEL 指定,在段内顺序由 CONFIG_APPLICATION_INIT_PRIORITY指定。rpc初始化时传入的错误回调函数有两个功能:

1.打印错误码

2.杀死线程

网络核初始化结束,我们看一下应用核初始化代码:

 首先是获取网络核初始化状态,整个流程具体代码如下图:

这里比较关键的函数为 int nrf_rpc_cbor_cmd(const struct nrf_rpc_group *group, uint8_t cmd,struct nrf_rpc_cbor_ctx *ctx,nrf_rpc_cbor_handler_t handler, void *handler_data);

它的作用就是向 group 里发送一条命令ID为 cmd 的命令,ctx 为固定的结构体,必须要用 NRF_RPC_CBOR_ALLOC 分配,发送完之后 cmd 的响应处理回调函数为 handler handler_data 会传递给 handler ,是 cmd 响应数据的指针。上文中已经提到,命令是需要响应的,而事件不需要。

group 这个上文也说过,应用核和网络核都要注册,且要一样,应用核中有:

网络核中有:

宏原型:

 参数依次为:群组名称,字符串名称(唯一),ack回调函数,ack回调数据指针,错误回调函数。

 可以看到后三个参数都可以为NULL!

继续回到获取远程初始化状态,使用 nrf_rpc_cbor_cmd 函数向 entropy_group 发送了一条ID为 RPC_COMMAND_ENTROPY_INIT(0x01) 的命令,这个命令ID是我们自己提供,范围在0~254,然后我们用 rsp_error_code_handle 函数去处理命令的响应数据。

而网络核对命令的处理如下:

可以看到关键就在于注册了和应用核里面一样的群组里面的,命令ID为0x01的解码器,并给它提供了回调函数,也就是在群组 entropy_group 里接到 0x01的命令就调用 entropy_init_handler 函数。而且在这里我们看到了怎么把一个 int64 型数据通过响应命令发给应用核,即调用:CborError cbor_encode_int(CborEncoder *encoder, int64_t value),这里 encoder 为ctx.encoder,value 即想要传递的数据。

从这里也可以看出来,两个核之间通信并不是使用的原始数据,而是由发送端编码,接收端解码,所有数据统一使用CBOR编码格式。

应用核解码如下:

这里有一个固定格式,即从Cbor类型的数据里解析数据时,要先判断数据类型,否则用错误的解析方式会引发不可预测的结果,每种数据类型都有它自己的解析方式!

从这里看到如果网络核初始化成功,则会发送错误码为0的响应信息,应用核在得到响应后,把返回的数据先判断是否为int类型,如果类型正确,会把数据存在 handler_data 里,也就是上层函数的 result 里return,最后在main()里判断是否为0。

接下来看应用核怎么获取entropy设备的数据:

传入一个buf长度为10的指针来存从网络核获取到的数据:

和之前不一样的是:

1.我们把要接收的数据长度(10)放进容器内发送给网络核了

2.我们把结构体 result 的指针给响应处理函数了,确保读出来的数据可以返回到上层函数。

与之前一样,网络核要注册命令ID为 0x02 的解码器:

可以看到,这几个命令都用的同一个回调函数,只是在触发回调的时候传入的参数不同,而在回调中通过判断传入的哪个参数去判断是哪个命令触发的回调。

 由于应用核在命令中发送给网络核一个buf长度,所以网络核在接收到数据后,先得到这个长度,然后再从设备entropy中获取这么多数据,发送回给应用核:

可以看到在返回给应用核的数据中,我们先填充的是错误码,再填充了10个字节的数据。

在应用核中数据解析为:

上面这种方式是应用核在发送cmd时,提供一个处理函数去处理响应返回的数据,下面则是不提供处理函数,直接处理返回数据:

可以看到和之前调用的发送函数相比,少了两个参数,分别是回调函数和回调函数的入参指针。而解码方式其实一模一样,不过需要注意的是,必须添加 nrf_rpc_cbor_decoding_done(&ctx.value);  

就和malloc()和free()一样,这里不添加会出现内存问题。

下面是事件的使用:

在main里有:

可以看到传入参数为buf长度和回调函数,回调函数内容为:

就是简单的打印。继续看事件的发送,如下:

 可以看到调用的函数没有处理回调,因为事件就是单向的。

在网络核,我们收到这个事件,所做处理如下:

 

 可以看到,和之前一样把数据放在容器里面,然后调用了事件发送函数,给应用核也发送了一个事件,而在应用核中,有注册这个事件的解码器:

这里callback在应用核第一次发送事件时初始化,其他内容和之前的几个大同小异。

之前两个发送 cmd 的流程都是,应用核发送,网络核响应,最后一个 cmd 发送流程为:应用核发送 cmd ,网络核收到后没有直接响应而是先也给应用核发送一个 cmd 再响应,应用核收到后响应。

首先,main()里:

和上个事件发送差不多,发送函数则和第一个获取远程初始化状态差不多:

可以看到发送了长度数据,然后提供了一个处理回调函数,而在网络核上有:

首先注册了命令解码器,然后在回调里调用 entropy_get_result ,然后用 rsp_error_code_send 去响应。发送数据函数如下:

应用核也注册了cmd解码器,收到信息后也需要响应:

可以看到和之前事件回调是同一个函数,只是多了一个响应。 

在函数使用过程中,函数名后缀为_no_err 的,表示此函数没有返回,因为它的返回值会直接发送给错误回调函数,而想要自己处理的,可以使用同名但没有后缀的函数。

关于工程说明可以参考文件夹entropy_nrf53下README.rst,RPC使用说明可以参考nrfxlib/nrf_rpc/doc/usage.rst ,大部分函数注释可以参考文件 nrf_rpc_cbor.h 和 nrf_rpc.h 。  

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
根据引用\[1\],在mcp2517fd-h/sl电路设计中,可以使用SPI接口来与微控制器进行通信。SPI通信的时序可以按照以下方式进行设置:将要写入的数据分别存储在spiTransmitBuffer数组的不同位置,例如spiTransmitBuffer\[0\]、spiTransmitBuffer\[1\]和spiTransmitBuffer\[2\]。其中,spiTransmitBuffer\[0\]用于存储命令和地址的高位,spiTransmitBuffer\[1\]用于存储地址的低位,spiTransmitBuffer\[2\]用于存储要传输的数据。 根据引用\[2\],MCP2517FD有多种模式可供选择,包括Configuration Normal、CAN FD Normal、CAN 2.0、Sleep、Listen Only、Restricted Operation以及Internal and External Loop back modes。这些模式可以根据具体需求进行配置。 根据引用\[3\],mcp2517fd使用SPI接口进行通信通信模式可以选择为模式1,1或0,0的8-bit模式。SFR和RAM的访问通过SPI命令进行。每个命令由4位命令和12位地址组成,并在nCS下降沿后的SCK上升沿开始传输,传输完成后nCS拉高。 综上所述,mcp2517fd-h/sl电路设计中可以使用SPI接口与微控制器进行通信,根据具体需求选择不同的模式,并按照SPI通信的时序进行数据传输。 #### 引用[.reference_title] - *1* [MCP2517FD(一)——简介](https://blog.csdn.net/wangguchao/article/details/106916842)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [MCP2517FD笔记](https://blog.csdn.net/shinn476391300/article/details/102390852)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值