⚠️
嗨,...感谢您来论坛。令人兴奋的消息!我们现在正在迁至我们的新论坛平台,将提供更好的功能,并包含在主对话框网站中。所有帖子和帐户都已迁移。我们现在只接受新论坛上的流量 - 请发布任何新线程https://www.dialog-seminile.com/support.。我们将在未来几天修复错误/优化搜索和标记。
10个帖子/ 0新
最后一篇
hamiddhosseini
离线
最后一次露面:6 months 2 weeks ago
加入:2020-05-12 12:04
UART中断

亲爱的对话支持团队,

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

关键词:
Device:
JK_DIALOG.
离线
最后一次露面:2 months 2 weeks ago
职员
加入:2016-08-22 23:07
嗨,我想你正在服用

嗨,我认为你正在采用正确的方法来与中断例子。当然,UART示例和BLE示例之间的差异是SDK。我猜你正在阻止:

虽然((!uart_receive_finished));

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.

hamiddhosseini
离线
最后一次露面:6 months 2 weeks ago
加入:2020-05-12 12:04
非常感谢乔恩,

非常感谢乔恩,

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

JK_DIALOG.
离线
最后一次露面:2 months 2 weeks ago
职员
加入:2016-08-22 23:07
嗨哈米德,

嗨哈米德,

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.

hamiddhosseini
离线
最后一次露面:6 months 2 weeks ago
加入:2020-05-12 12:04
Dear Jon,

Dear Jon,

我已经实施了我们讨论的更改。我的代码现在看起来像这样:

/ /主循环在arch_main.c (1) {{wdg_reload(WATCHDOG_DEFAULT_PERIOD); // schedule all pending events schedule_while_ble_on(); } while (app_asynch_proc() != GOTO_SLEEP); //grant control to the application, try to go to power down //if the application returns GOTO_SLEEP // in user_peripheral.c arch_main_loop_callback_ret_t user_app_on_system_powered(void) { if (!uart_receive_finished){ //wdg_reload(WATCHDOG_DEFAULT_PERIOD); return KEEP_POWERED; } else{ connected_governor(); return KEEP_POWERED; } } // in my code #define TEMP_QUEUE_MAX_LENGTH 1 static char temp_queue; 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 ++; return; } else if ((index>1) && (index < temp_length + 3)){ queue[index] = temp_queue; index ++; return; } else if (index == (temp_length+3)){ queue[index] = temp_queue; 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 == NC_SOM_TYPE_SENSOR ){ queue[index] = temp_queue; index ++; SOM_RECEIVED = true; return; } else{ index = 0; SOM_RECEIVED = false; uart_receive_finished = false; data_received_cnt = 0; return; } } void uart_receive_intr_init(uart_t *uart){ //Configure the UART to receive more data 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); } void uart_receive_intr_example(uart_t* uart) { if (chk_queue(data_received_cnt)){ process_buffer((uint8_t *)buffer,buffer_received_cnt); } //Reconfigure the UART to reset the receiving! uart_receive_intr_init(uart); }

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

JK_DIALOG.
离线
最后一次露面:2 months 2 weeks ago
职员
加入:2016-08-22 23:07
嗨哈米德,

嗨哈米德,

几个评论。

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.

hamiddhosseini
离线
最后一次露面:6 months 2 weeks ago
加入:2020-05-12 12:04
1)好的,自从我以后想到

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在循环中触发。似乎仍然存在无限循环的问题?

JK_DIALOG.
离线
最后一次露面:2 months 2 weeks ago
职员
加入:2016-08-22 23:07
嗨哈米德,

嗨哈米德,

请在user_app_on_system_powered的看门狗重新加载中添加回来,但只是将它放在if()语句之外:

wdg_reload(WATCHDOG_DEFAULT_PERIOD);

/ Jon.

hamiddhosseini
离线
最后一次露面:6 months 2 weeks ago
加入:2020-05-12 12:04
Dear 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.

//user_peripheral.chrach_main_loop_callback_ret_t user_app_on_system_powered(void){wdg_reload(watchdog_default_period);如果(!uart_receive_finished){return keep_powered;} else {connected_governor();返回keep_powered;}} //我的文件void连接_governor(){//将在UART_RECEIVE_FININMENT上调用此函数。//它检查收到的消息并包含状态机。UART_RECEIVE_INTR_EXAMPLE(UART2);//重新配置UART以重置接收!UART_RECEIVE_INTR_INIT(UART2);void uart_receive_intr_cb(uint16_t长度){if(temp_queue_1 == som_char){uart_receive_finishing = true; return; } } void uart_receive_intr_init(uart_t *uart){ //Configure the UART to receive more data uart_receive_finished = false; data_received_cnt = 0; uart_register_rx_cb(uart, uart_receive_intr_cb); uart_receive(uart, (uint8_t *)(&temp_queue_1), 1, UART_OP_INTR); } void uart_receive_intr_example(uart_t* uart) { printf_string(uart,"SOM"); }
Generally, I want the UART to wait for this one character (SOM_CHAR), upon receiving this one, the UART should start to record the incoming data for a given length (it's the second transmitted byte in this case).

如果我将队列表单1byte的大小更改为一些更大的数字,则程序将起作用,但我必须等待队列满满的回调。这将增加我的系统的响应时间和减少QoS。此外,此队列大小需要大于任何收到的消息。
在UART配置似乎完好无损时,我找不到接收线状态错误后面的原因。

Regards,

Hamid

hamiddhosseini
离线
最后一次露面:6 months 2 weeks ago
加入:2020-05-12 12:04
好的,最后我已经管理了

好的,最后我已经管理了to make it work.

Thanks a lot Jon