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

亲爱的对话框支持团队,

我正试图通过UART接收一些数据,并在一些处理后通过BLE发送它。到目前为止,我用了ble_app_peripheralble_uart实例创建我需要什么。

Initialy我用了一个app_easy_timer要启动调整器每2秒来处理任何接收的数据并通过BLE发送它们。这位州长会使用uart_receive()DMA模式。这完美地工作,但是,我想提高程序的响应时间的意思,我想总督在UART总是等待数据传送开始。

我尝试以下,但reahing while循环后的程序崩溃。

volatile bool som_received = false;静态void UART_RECEIVE_INTR_CB(UINT16_T长度){静态UINT8_T索引= 0;Static uint8_t temp_length = 0;if(som_received){if(index == 1){temp_length = temp_queue [index];指数+ +;返回;}否则if((index> 1)&&(index 

我在等待一个SOM字符,数据长度和数据本身。也就是说;我把这些值存储在队列中,在接收到一个数据包后,我在改变uart_receive_finished为true。

我有以下问题:

1-是否有一种方法,板可以一直等待数据(监听UART)在后台?在始终等待并通过UART存储传入数据的同时,板应该运行其正常的进程(可能是检查当前状态和是否接收到任何数据的状态机)。

2-我猜测我当前的代码有问题的问题(有或没有看门狗,问题仍然存在!)。我试过修改uart_rx_timeout_isr小号Ø将停止无限循环,但没有奏效。请您简要介绍一下此中断和超时?

问候,

汉米德

关键词:
设备:
JK_Dialog
离线
最后一次露面:5个月2个星期前
职员
加入:2016年8月22日23:07
您好,我想你正在服用

嗨,我认为你正在与中断例如正确的做法。UART的例子和实施例BLE之间的区别是,当然,在SDK。我猜你是阻塞:

而(!(uart_receive_finished));

这导致了看门狗起火。

我会做的是以下情况:

1)使用UART_REGISTER_RX_CB初始化UART驱动程序,并在user_callbacks_config中的.app_on_init回调中的uart_initialize .h

2)在user_callback_config.h创建自己的功能点.app_on_system_powered(这是一个钩子直接进入主循环)。

3)现在,在您的UART回调函数中,在获取有效数据时设置您的UART_RECEIDED_DATA标志。

4)在app_on_system_powered回调中,只需检查标志,如果未设置,则允许它返回。

该SDK运行调度一旦app_on_system_powered有跑,所以这不应该被阻挡一段时间。

请让我知道这可不可以帮你。

/乔恩

Hamiddhosseini
离线
最后一次露面:9个月1周前
加入:2020-05-12上午
非常感谢乔恩,

非常感谢乔恩,

我已经实施了你在此提到的步骤,我实际上可以更好地了解整个系统。换句话说app_asynch_proc在主循环不断直到该shcedulerapp_on_system_powered.回报去睡觉命令。

但是,您提到的步骤似乎没有工作。当我运行该程序时,看门狗在广告开始后立即触发并停止程序。这是我的user_app_on_system_powered:

ARCH_MAIN_LOOP_CALLBACK_RET_T USER_APP_ON_SYSTEM_POWERED(void)
{
如果(!uart_receive_finished){
返回KEEP_POWERED;
}
别的{
返回goto_sleep;
}
}

事实上,当我在这个函数的开始处放置一个断点时,我就能够沿着所需的路径使程序继续运行,而它仍然在等待uart_receive_finished。然而,除去休息POIN并允许程序继续其进程将导致我无法跟踪崩溃。

问候,

汉米德

JK_Dialog
离线
最后一次露面:5个月2个星期前
职员
加入:2016年8月22日23:07
嗨哈米德

嗨哈米德

如果您完全结束,您只能返回Goto_Sleep。但是在这里预期看门狗射击。看门狗只是在主循环中'反馈',一旦您返回Goto_Sleep,就会才会在主循环中。在user_callback_config.h中的注释中也提到了这一点.App_on_system_powered。

如果你在很长一段时间内返回KEEP_POWERED,请在你的循环中使用以下代码行:

wdg_reload (WATCHDOG_DEFAULT_PERIOD);

/乔恩

Hamiddhosseini
离线
最后一次露面:9个月1周前
加入:2020-05-12上午
亲爱的乔恩,

亲爱的乔恩,

我实现了我们讨论的变化。我的代码现在看起来是这样的:

//在arch_main.c的主循环while(1) {do {wdg_reload(WATCHDOG_DEFAULT_PERIOD);//调度所有挂起事件schedule_while_ble_on();} while (app_asynch_proc() != GOTO_SLEEP);//grant control to the application, try to go to power down //如果应用返回GOTO_SLEEP //在user_peripheral.c arch_main_loop_callback_ret_t user_app_on_system_powered(void) {if (!uart_receive_finished){//wdg_reload(WATCHDOG_DEFAULT_PERIOD);返回KEEP_POWERED;其他}{connected_governor ();返回KEEP_POWERED;}} //在我的代码#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); }

但是,现在我有另一个问题。在接收到第一个字节并返回到UART中断处理程序时,为下一个字节,接收线状态中断被解雇,在一个无限循环,导致程序崩溃。我怀疑我不得不释放或刷新接收缓冲区不知何故,你可向我们提供了一些指导?

问候,

汉米德

JK_Dialog
离线
最后一次露面:5个月2个星期前
职员
加入:2016年8月22日23:07
嗨哈米德

嗨哈米德

意见夫妇。

1)WDOG已在主循环中重新加载,您应该避免修改此文件。

2)是否在任何事务期间重新配置UART ?您应该只需要设置UART一次,然后在每个字节上触发中断。如果您在传输期间重新配置UART,这将导致帧/奇偶校验错误。

/乔恩

Hamiddhosseini
离线
最后一次露面:9个月1周前
加入:2020-05-12上午
1)好吧,我没有想到过

1)好的,我想自从我是谷歌以保持CPU运行一段时间,我应该重新加载调度程序循环内的看门狗。但是,它已经在大主循环的末尾重新加载;我删除了主文件上的修改(wdog_reload在调度循环中)。谢谢你的评论。

2)I是重新配置所述UART各自接收wasfinished之后。看来,这是造成问题。我已删除了这部分也是如此。

现在,当我在启动广告后一步一步运行程序时,该过程顺利进行。换句话说,主循环检查去睡觉每一次和等待uart_receive_finished。然而,当我正常运行的程序,看门狗再次发射。正如我可以跟踪这个,看门狗在这个while循环解雇。似乎还有与无限循环的问题吗?

JK_Dialog
离线
最后一次露面:5个月2个星期前
职员
加入:2016年8月22日23:07
嗨哈米德

嗨哈米德

请加回在你user_app_on_system_powered看门狗重装,但只是把它放在外面的,如果()语句:

wdg_reload (WATCHDOG_DEFAULT_PERIOD);

/乔恩

Hamiddhosseini
离线
最后一次露面:9个月1周前
加入:2020-05-12上午
亲爱的乔恩,

亲爱的乔恩,

非常感谢,现在看门狗的问题解决了。然而,我还是有个问题接收器线状态错误中断。

我已经尽量简化了代码。在这段代码中,uart应该只等待一个特殊字符。

//user_peripheral.c arch_main_loop_callback_ret_t user_app_on_system_powered(无效){wdg_reload(WATCHDOG_DEFAULT_PERIOD);(!uart_receive_finished)如果{返回KEEP_POWERED;其他}{connected_governor ();返回KEEP_POWERED;}} //我的文件无效connected_governor(){//这个函数会呼吁uart_receive_finished。//它检查所接收的消息,并且包含状态机。uart_receive_intr_example(UART2);//重新配置UART重置接收!uart_receive_intr_init(UART2);}空隙uart_receive_intr_cb(uint16_t长度){如果(temp_queue_1 == SOM_CHAR){uart_receive_finished = 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"); }
通常,我希望UART等待这个字符(SOM_CHAR),当接收到这个字符时,UART应该开始记录给定长度的传入数据(在本例中是第二个传输字节)。

如果我改变了队列形式1字节的大小,一些较大的数量,程序的工作,但我不得不等待队列满有回调。这会增加我的系统的响应时间,降低服务质量。此外,该队列的大小需要比任何接收到的消息更大。
我找不到当UART配置似乎是完整的被解雇背后Reciever行状态错误的原因。

问候,

汉米德

Hamiddhosseini
离线
最后一次露面:9个月1周前
加入:2020-05-12上午
好了,最后我成功

好了,我终于成功了。

谢谢很多Jon