| 293 | } |
| 294 | |
| 295 | rt_err_t rt_vbus_post(rt_uint8_t id, |
| 296 | rt_uint8_t prio, |
| 297 | const void *data, |
| 298 | rt_size_t size, |
| 299 | rt_int32_t timeout) |
| 300 | { |
| 301 | rt_err_t err = RT_EOK; |
| 302 | struct rt_vbus_pkg pkg; |
| 303 | unsigned int putsz; |
| 304 | const unsigned char *dp; |
| 305 | |
| 306 | if (!_bus_out_que) |
| 307 | { |
| 308 | rt_kprintf("post (data: %p, size: %d, timeout: %d) " |
| 309 | "to bus before initialition\n", |
| 310 | data, size, timeout); |
| 311 | return -RT_ERROR; |
| 312 | } |
| 313 | |
| 314 | if (id >= RT_VBUS_CHANNEL_NR) |
| 315 | return -RT_ERROR; |
| 316 | |
| 317 | if (timeout != 0) |
| 318 | { |
| 319 | RT_DEBUG_IN_THREAD_CONTEXT; |
| 320 | } |
| 321 | |
| 322 | #ifdef RT_VBUS_USING_FLOW_CONTROL |
| 323 | while (_chn_status[id] == RT_VBUS_CHN_ST_SUSPEND) |
| 324 | { |
| 325 | rt_thread_t thread; |
| 326 | |
| 327 | if (timeout == 0) |
| 328 | { |
| 329 | return -RT_EFULL; |
| 330 | } |
| 331 | |
| 332 | thread = rt_thread_self(); |
| 333 | thread->error = RT_EOK; |
| 334 | /* We only touch the _chn_suspended_threads in thread, so lock the |
| 335 | * scheduler is enough. */ |
| 336 | rt_enter_critical(); |
| 337 | rt_thread_suspend(thread); |
| 338 | |
| 339 | rt_list_insert_after(&_chn_suspended_threads[id], &RT_THREAD_LIST_NODE(thread)); |
| 340 | if (timeout > 0) |
| 341 | { |
| 342 | rt_tick_t timeout_tick = timeout; |
| 343 | rt_timer_control(&(thread->thread_timer), |
| 344 | RT_TIMER_CTRL_SET_TIME, |
| 345 | &timeout_tick); |
| 346 | rt_timer_start(&(thread->thread_timer)); |
| 347 | } |
| 348 | /* rt_exit_critical will do schedule on need. */ |
| 349 | rt_exit_critical(); |
| 350 | |
| 351 | if (thread->error != RT_EOK) |
| 352 | return thread->error; |
no test coverage detected