static struct vsfsm_state_t *hci_transport_h4_evt_handler(struct vsfsm_t *sm, vsfsm_evt_t evt) { struct hci_transport_h4_param_t *h4param = (struct hci_transport_h4_param_t *)sm->user_data; struct vsf_bufstream_t *bufstream; uint8_t *ptr; switch (evt) { case VSFSM_EVT_INIT: { struct usart_stream_t *usart_stream = h4param->usart_stream; struct vsf_stream_t *stream; h4param->rx.stream.mem.read = false; stream = usart_stream->stream_rx = &h4param->rx.stream.stream; stream->op = &bufstream_op; stream->callback_rx.param = h4param; stream->callback_rx.on_inout = hci_transport_h4_on_in; usart_stream_init(usart_stream); stream_connect_rx(usart_stream->stream_rx); } break; case HCI_EVT_IN: if (h4param->rx.state == HCI_RX_RECEIVED) { bufstream = &h4param->rx.stream; ptr = &h4param->rx.buffer[HCI_INCOMING_PRE_SIZE]; h4param->packet_handler(ptr[0], &ptr[1], (bufstream->mem.buffer.buffer - ptr) + bufstream->mem.buffer.size - 1); h4param->rx.state = HCI_RX_IDLE; hci_transport_h4_on_in(h4param); } break; } return NULL; }这里是任务的事件驱动代码,INIT事件中,初始化了接收流,类型是bufstream。对于bufstream,可以自己看VSF中,component/fundation/stream里的代码。 然后初始化串口流,对于接收串口数据来说,串口流模块是发送端,因为串口流模块在接收到串口数据的时候,会写入到流,发送端可以写数据到流。 串口流初始化后,实际上接收流的发送端就连接上了,后面就是连接接收端,这样流就可以运行了。 这里一个关键的函数是:hci_transport_h4_on_in,在接收流收到数据的时候被调用,注意,这个函数是可能在中断中被调用的。 复制static void hci_transport_h4_on_in(void *param) { struct hci_transport_h4_param_t *h4param = (struct hci_transport_h4_param_t *)param; struct vsf_bufstream_t *bufstream = &h4param->rx.stream; uint8_t *ptr = &h4param->rx.buffer[0]; struct vsf_buffer_t buffer; if (h4param->opened) { if (STREAM_GET_FREE_SIZE(bufstream)) return; switch (h4param->rx.state) { case HCI_RX_IDLE: hci_transport_h4_idle: h4param->rx.state++; buffer.buffer = ptr; buffer.size = 1; break; case HCI_RX_TYPE: h4param->rx.state++; buffer.buffer = &ptr[1]; switch (ptr[0]) { case HCI_ACL_DATA_PACKET: buffer.size = HCI_ACL_HEADER_SIZE; break; case HCI_SCO_DATA_PACKET: buffer.size = HCI_SCO_HEADER_SIZE; break; case HCI_EVENT_PACKET: buffer.size = HCI_EVENT_HEADER_SIZE; break; default: hci_transport_h4_reset: h4param->rx.state = HCI_RX_IDLE; goto hci_transport_h4_idle; } break; case HCI_RX_HEADER: switch (ptr[0]) { case HCI_ACL_DATA_PACKET: buffer.size = GET_LE_U16(&ptr[3]); buffer.buffer = &ptr[1 + HCI_ACL_HEADER_SIZE]; if (HCI_ACL_HEADER_SIZE + buffer.size > HCI_PACKET_BUFFER_SIZE) goto hci_transport_h4_reset; break; case HCI_SCO_DATA_PACKET: buffer.size = ptr[3]; buffer.buffer = &ptr[1 + HCI_SCO_HEADER_SIZE]; break; case HCI_EVENT_PACKET: buffer.size = ptr[2]; buffer.buffer = &ptr[1 + HCI_EVENT_HEADER_SIZE]; break; } h4param->rx.state++; if (buffer.size) break; case HCI_RX_DATA: h4param->rx.state++; vsfsm_post_evt_pending(&h4param->sm, HCI_EVT_IN); case HCI_RX_RECEIVED: return; } STREAM_READ(bufstream, &buffer); } }在启动的时候,会调用一次hci_transport_h4_on_in,这时候,rx.state是IDLE,会设置buffer接收1个字节报文类型(通过调用STREAM_READ)。 然后,这里就是一个状态机了,在RX_DATA接受完数据后,就发送HCI_EVT_IN事件,并且进入RECEIVED状态,等到高层处理完事件后,重新初始化接收状态机启动接收。
static void hci_transport_h4_on_in(void *param) { struct hci_transport_h4_param_t *h4param = (struct hci_transport_h4_param_t *)param; struct vsf_bufstream_t *bufstream = &h4param->rx.stream; uint8_t *ptr = &h4param->rx.buffer[0]; struct vsf_buffer_t buffer; if (h4param->opened) { if (STREAM_GET_FREE_SIZE(bufstream)) return; switch (h4param->rx.state) { case HCI_RX_IDLE: hci_transport_h4_idle: h4param->rx.state++; buffer.buffer = ptr; buffer.size = 1; break; case HCI_RX_TYPE: h4param->rx.state++; buffer.buffer = &ptr[1]; switch (ptr[0]) { case HCI_ACL_DATA_PACKET: buffer.size = HCI_ACL_HEADER_SIZE; break; case HCI_SCO_DATA_PACKET: buffer.size = HCI_SCO_HEADER_SIZE; break; case HCI_EVENT_PACKET: buffer.size = HCI_EVENT_HEADER_SIZE; break; default: hci_transport_h4_reset: h4param->rx.state = HCI_RX_IDLE; goto hci_transport_h4_idle; } break; case HCI_RX_HEADER: switch (ptr[0]) { case HCI_ACL_DATA_PACKET: buffer.size = GET_LE_U16(&ptr[3]); buffer.buffer = &ptr[1 + HCI_ACL_HEADER_SIZE]; if (HCI_ACL_HEADER_SIZE + buffer.size > HCI_PACKET_BUFFER_SIZE) goto hci_transport_h4_reset; break; case HCI_SCO_DATA_PACKET: buffer.size = ptr[3]; buffer.buffer = &ptr[1 + HCI_SCO_HEADER_SIZE]; break; case HCI_EVENT_PACKET: buffer.size = ptr[2]; buffer.buffer = &ptr[1 + HCI_EVENT_HEADER_SIZE]; break; } h4param->rx.state++; if (buffer.size) break; case HCI_RX_DATA: h4param->rx.state++; vsfsm_post_evt_pending(&h4param->sm, HCI_EVT_IN); case HCI_RX_RECEIVED: return; } STREAM_READ(bufstream, &buffer); } }在启动的时候,会调用一次hci_transport_h4_on_in,这时候,rx.state是IDLE,会设置buffer接收1个字节报文类型(通过调用STREAM_READ)。 然后,这里就是一个状态机了,在RX_DATA接受完数据后,就发送HCI_EVT_IN事件,并且进入RECEIVED状态,等到高层处理完事件后,重新初始化接收状态机启动接收。
收藏0 举报
27
60
6
扫码关注 21ic 官方微信
扫码关注嵌入式微处理器
扫码关注电源系统设计
扫码关注21ic项目外包
扫码浏览21ic手机版
本站介绍 | 申请友情链接 | 欢迎投稿 | 隐私声明 | 广告业务 | 网站地图 | 联系我们 | 诚聘英才
京公网安备 11010802024343号