mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
19383: cord: include gcoap_req_send returning 0 in error r=benpicco a=bergzand ### Contribution description gcoap_req_send returns 0 if it was unable to send the CoAP request. CoRD did not include that case in the return code checks. This changes CoRD to include it and drop the registration if CoAP could not send the request. The old behaviour made the CoRD thread lock up. ### Testing procedure - Check with the gcoap API docs. - I can reliable trigger the issue with a RIOT application including both the `cord_ep_standalone` module and some measurement reported both sending requests to the same application. If at some point the application is shut down, gcoap has all its memo's occupied with the measurement reporting and can't add the CoRD update request. Thus the CoRD update request fails with a zero code and the thread (previously) would lock up. ### Issues/PRs references None 19385: cpu/stm32/periph/timer: fix clobered IRQ flag r=benpicco a=Enoch247 ### Contribution description From the git commit: > The STM32 periph_timer driver reads the timer's status flags, then clears them all. It is possible that a timer interrupt could occur between reading the flag and clearing it. This would lead to a lost interrupt. > > The timer's status flags can be cleared by software, but can only be set by the hardware. This patch takes advantage of this by only clearing the flags it knows are set. The rest of the flags are set, which doesn't actually change their state. I had trouble finding anything in ST's datasheet saying that software could not set the timer's status flags, but testing showed that this is how it works in practice. Further, [ST's own HAL ](https://github.com/STMicroelectronics/STM32CubeF4/blob/master/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h#L1258)confirms this. If the hardware didn't work this way, it would be impossible to atomically read-modify-write the flags. ### Testing procedure I tested by doing the following: 1. `make -C tests/periph_timer BOARD=nucleo-f767zi all flash term` 2. press s 3. press [ENTER] 4. observe test passes 5. `make -C tests/periph_timer_periodic BOARD=nucleo-f767zi all flash term` 6. press s 7. press [ENTER] 8. observe test passes 9. `make -C tests/periph_timer_short_relative_set BOARD=nucleo-f767zi all flash term` 10. press s 11. press [ENTER] 12. observe test passes ### Issues/PRs references - none known Co-authored-by: Koen Zandberg <koen@bergzand.net> Co-authored-by: Joshua DeWeese <jdeweese@primecontrols.com>
This commit is contained in:
commit
9142d9c375
@ -267,7 +267,12 @@ static inline void irq_handler(tim_t tim)
|
||||
{
|
||||
uint32_t top = dev(tim)->ARR;
|
||||
uint32_t status = dev(tim)->SR & dev(tim)->DIER;
|
||||
dev(tim)->SR = 0;
|
||||
|
||||
/* clear interrupts which we are about to service */
|
||||
/* Note, the flags in the SR register can be cleared by software, but
|
||||
* setting them has no effect on the register. Only the hardware can set
|
||||
* them. */
|
||||
dev(tim)->SR = ~status;
|
||||
|
||||
for (unsigned int i = 0; status; i++) {
|
||||
uint32_t msk = TIM_SR_CC1IF << i;
|
||||
|
@ -151,8 +151,10 @@ static int _update_remove(unsigned code, gcoap_resp_handler_t handle)
|
||||
ssize_t pkt_len = coap_opt_finish(&pkt, COAP_OPT_FINISH_NONE);
|
||||
|
||||
/* send request */
|
||||
gcoap_req_send(buf, pkt_len, &_rd_remote, handle, NULL);
|
||||
|
||||
ssize_t send_len = gcoap_req_send(buf, pkt_len, &_rd_remote, handle, NULL);
|
||||
if (send_len <= 0) {
|
||||
return CORD_EP_ERR;
|
||||
}
|
||||
/* synchronize response */
|
||||
return _sync();
|
||||
}
|
||||
@ -224,7 +226,7 @@ static int _discover_internal(const sock_udp_ep_t *remote,
|
||||
coap_opt_add_uri_query(&pkt, "rt", "core.rd");
|
||||
size_t pkt_len = coap_opt_finish(&pkt, COAP_OPT_FINISH_NONE);
|
||||
res = gcoap_req_send(buf, pkt_len, remote, _on_discover, NULL);
|
||||
if (res < 0) {
|
||||
if (res <= 0) {
|
||||
return CORD_EP_ERR;
|
||||
}
|
||||
return _sync();
|
||||
@ -295,7 +297,7 @@ int cord_ep_register(const sock_udp_ep_t *remote, const char *regif)
|
||||
|
||||
/* send out the request */
|
||||
res = gcoap_req_send(buf, pkt_len, remote, _on_register, NULL);
|
||||
if (res < 0) {
|
||||
if (res <= 0) {
|
||||
retval = CORD_EP_ERR;
|
||||
goto end;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user