亲爱的对话支持团队,
I'm trying to receive some data via UART and after some processing send it via BLE. So far, I've used theble_app_peripheralandBLE_UART.示例以创建我需要的东西。
渴望我用了一个app_easy_timer.to to start a governor every 2s to process any received data and send them via BLE. This governor would useUART_RECEIVE()在DMA模式。然而,这完美无缺;我想提高程序的响应时间,这意味着我希望总督总是等待UART进行数据传输开始。
我尝试了以下几个,但在循环中缩短后程序崩溃。
volatile bool SOM_RECEIVED = false; static void uart_receive_intr_cb(uint16_t length){ static uint8_t index = 0; static uint8_t temp_length = 0; if (SOM_RECEIVED){ if (index == 1){ temp_length = temp_queue[index]; index ++; return; } else if ((index>1) && (index < temp_length + 3)){ queue[index] = temp_queue[index]; index ++; return; } else if (index == (temp_length+3)){ queue[index] = temp_queue[index]; uart_receive_finished = true; data_received_cnt = length; SOM_RECEIVED = false; index = 0; return; } else{ SOM_RECEIVED = false; index = 0; return; } } else if (temp_queue[index] == SOM_CHAR ){ queue[index] = temp_queue[index]; index ++; SOM_RECEIVED = true; return; } else{ index = 0; SOM_RECEIVED = false; uart_receive_finished = false; data_received_cnt = 0; return; } } void uart_receive_intr_example(uart_t* uart) { uart_receive_finished = false; data_received_cnt = 0; uart_register_rx_cb(uart, uart_receive_intr_cb); uart_receive(uart, (uint8_t *)temp_queue, TEMP_QUEUE_MAX_LENGTH, UART_OP_INTR); while ((!uart_receive_finished)); if (chk_queue(data_received_cnt)) { printf_string(UART2,"B"); for (int8_t i = 0; i < buffer_received_cnt; i++) printf_byte(uart,buffer[i]); process_buffer((uint8_t *)buffer,buffer_received_cnt); } }
I'm waiting for a SOM character, length of data and the data itself. That being said; I'm storing these values in queue and after receiving one packet of data I'm changinguart_receive_finished.为真。
我有以下问题:
1- Is there a way that the board can be always waiting for data (listening to UART) in the background? The board should be running its normal process (maybe a state machine that checks the current state and whether any data has been received or not) while always waiting and storing the incoming data via UART.
2- I'm guessing that my current code has a problem with the time out (with or without the watchdog the problem still exists!). I've tried modifying theUART_RX_TIMEOUT_ISR S.o它会阻止无限循环,但这并不起。你能解释一下这个中断和超时吗?
Regards,
Hamid
嗨,我认为你正在采用正确的方法来与中断例子。当然,UART示例和BLE示例之间的差异是SDK。我猜你正在阻止:
And this is causing a watchdog to fire.
我所做的就是如下:
1)使用UART_REGISTER_RX_CB初始化UART驱动程序,并在user_callbacks_config中的.app_on_init回调中的uart_initialize .h
2)在user_callback_config中创建自己的函数,指向.app_on_system_powered(这是一个钩子直接进入主循环)。
3) Now, in your uart callback function set your uart_received_data flag when you get valid data.
4) In the app_on_system_powered callback, just check the flag and if it isn't set allow it to return.
SDK运行调度程序一旦App_on_System_Powered已运行,因此不应阻止一段时间。
请让我知道这可不可以帮你。
/ Jon.
非常感谢乔恩,
I've implemented the steps you mentioned here and I actually understood the whole system a bit better. In other wordsapp_asynch_proc.在主循环中让Shccululer保持直接app_on_system_powered返回A.去睡觉命令。
However, the steps you mentioned doesn't seem to work. When I run the program, the watchdog fires and stops the program right after the advertisement has begun. Here is myuser_app_on_system_powered:
arch_main_loop_callback_ret_t user_app_on_system_powered(void)
{
如果(!uart_receive_finished){
返回keep_powered;
}
别的{
return GOTO_SLEEP;
}
}
As a matter of fact, when I put a breakpoint at the beggining of this function, I'm able to follow the desired path to keep the program on while it's still waiting for theuart_receive_finished.。但是,删除了Break Poin并允许程序继续其过程将导致我无法追踪的崩溃。
Regards,
Hamid
嗨哈米德,
You should only return GOTO_SLEEP if you UART is completely finished. But the watchdog firing is expected here. The watchdog is only 'fed' in the main loop, once you've returned GOTO_SLEEP. This is also mentioned in the comments in the user_callback_config.h for .app_on_system_powered.
If you are returning KEEP_POWERED for an extended period of time, please use the following line of code in your loop:
wdg_reload(WATCHDOG_DEFAULT_PERIOD);
/ Jon.
Dear Jon,
我已经实施了我们讨论的更改。我的代码现在看起来像这样:
However, now I'm having another problem. Upon receiving the first byte and returning to the UART interrupt handler, for the next bytes,Receiver line status interrupt被射击并在无限循环中,导致程序崩溃。我怀疑我必须以某种方式释放或冲洗接收缓冲区,可以向我提供一些指示吗?
Regards,
Hamid
嗨哈米德,
几个评论。
1) wdog已经重新加载在主循环nd you should refrain from modifying this file.
2) Are you reconfiguring the UART during any of the transaction? You should just need to setup the UART once, and then interrupt will fire on each byte. If you are reconfiguring the UART during a transmission, this will cause framing/parity errors.
/ Jon.
1)好的,自从我以后想到was goint to keep the cpu running for a while I should reload the watchdog inside the scheduler loop. However, it's already being reloaded at the end of the big main loop, therefore; I removed the modifications on the the main file (wdog_reload.在调度程序循环中)。谢谢你的评论。
2)每次接受未完成后,我正在重新配置UART。似乎这导致了这个问题。我也删除了这个部分。
Now when I run the program step by step after starting the advertisement, the process goes on smoothly. In other words, the main loop checks for去睡觉every time and waits foruart_receive_finished.。但是,当我正常运行该程序时,看门狗再次被解雇。正如我可以跟踪的那样,WatchDog在循环中触发。似乎仍然存在无限循环的问题?
嗨哈米德,
请在user_app_on_system_powered的看门狗重新加载中添加回来,但只是将它放在if()语句之外:
wdg_reload(WATCHDOG_DEFAULT_PERIOD);
/ Jon.
Dear Jon,
Thanks a lot, now the problem with the watchdog is fixed. However, I'm still having the problem withReceiver line status error interrupt.
I've tried to simplify the code as much as possible. In this code, the uart is supposed to just wait for one special character.
如果我将队列表单1byte的大小更改为一些更大的数字,则程序将起作用,但我必须等待队列满满的回调。这将增加我的系统的响应时间和减少QoS。此外,此队列大小需要大于任何收到的消息。
在UART配置似乎完好无损时,我找不到接收线状态错误后面的原因。
Regards,
Hamid
好的,最后我已经管理了to make it work.
Thanks a lot Jon