at minute 25:37, you perform an SPI transaction from within an ISR?
Рік тому
Yes. In the use case for the demo, an interrupt for SPI should not block for that long and since the peripherals used inside of the ISR are not used anywhere else in the code, there should be no problem with race register access. It's an isolated case, but not a rare one. I've had a system designed without an RTOS and we used RTC ISR to trigger "precisely" spaced interrupts for sampling SPI ADCs for example. As my work colleague would say: "If you don't measure it, don't poke it". In that case, SPI is quite fast (10Mhz) and it only transfers 16 bits from each sensor, so the whole ISR was quite short and plenty fast for the sampling rate. Context matters and can ease the design.
Thank you for the valuable content. I would be grateful if you could assist me in answering a question. Regardless of whether the interrupt type is ISR or NVIC, if a falling edge triggers a signal that is going to be sent out through a digital output after a specific delay, and if this delay takes so long that another falling edge occurs at the same time the MCU is sending out that signal, the Interrupt Service Routine will interrupt the main program responsible for sending out the second signal, resulting in the second signal not being sent out as intended. I have already posted this issue on the forum, but I have not received any new information thus far. Does this explanation make sense to you?
Рік тому
Let me summarize your problem so that I can confirm if I understand it correctly. You have a signal, like an external digital signal, that triggers an interrupt. That interrupt starts a signal generation, which happens in main. I assume that you have a variable for the communication between interrupt and main. Main program will wait a set delay amount before signal is generated. In case, another interrupt arrives, which would create another request to start a signal generation from main, you are worried, that it might be corrupted? I think I understand your situation or at least I have a few similar scenarios in my head similar to your problem. Can you confirm that? If so, one answer is that you need to specify the behaviour of the signal generation trigger. You can use another variable, which is written to by main and read by interrupt, which specifies if the main loop is still processing/generating signal. If that's the case, interrupt service routine should just exit, thus ignore the trigger signal. You can also use the trigger variable as a busy signal. If not set, ISR will set it, maybe do something else. When main reads it, it starts signal generation. If the ISR implementation is so simple, it can just keep setting the trigger signal "to 1" and main won't do anything, since it's still processing the first signal generation. When main is done, it can set the shared signal variable "to 0". In the case, that you DO do something in the ISR, such as start a timer or any other peripheral, I would strongly suggest adding more status and/or synchronization mechanism either to the interrupt or the main, depending where the most time consuming part is beeing held, like the delay. You can also implement delay as a "state" in the signal generation state machine. With frequent polling you can check the state of the machine.
@ I really appreciate your help, thank you! I'm not sure if I explained the problem as I should. I have a signal (S1) which is coming from an external hall sensor and has the form of a square signal with a frequency of max. 25 Hz. I want to detect the falling edges of this signal a send out another signal (S2) through a DO after a specific delay after every falling edge. So the square signal simply triggers the signal I want to send out. The delay value is going to adjusted through a Potentiometer. The code that specifies the form of S2 is written in the main program. Everything works perfect besides when sending out S2 by the main interferes with a new falling edge of S1 which is detected by the ISR. When this happens the S2 starts behaving like it's triggered by the falling edge anymore. The Problem is that I'm not allowed to ignore any of the falling edges. So if put a variable that checks if the main is still sending out S2 and just exit the ISR when it's the case I assure that new falling edge will be "ignored".
@@ezz6928 I understand your issue more clearly now. You have an external signal (S1) triggering an interrupt to generate another signal (S2) with a specific delay, and you can't ignore any of the falling edges of S1. When the main program generates S2, it interferes with a new falling edge of S1, causing unexpected behavior in S2. To address this issue, you can implement a more robust synchronization mechanism between the main program and the interrupt service routine (ISR). Here's a possible approach: Shared Variable: Create a shared variable, let's call it s2GenerationInProgress, which will be used to indicate whether the main program is currently generating S2. Main Program: Before starting the S2 generation process, check the s2GenerationInProgress variable. If it's set (meaning S2 generation is in progress), wait until it's cleared before proceeding. Once it's cleared, set s2GenerationInProgress to indicate that the main program is now generating S2. Generate S2 as planned. ISR: When the falling edge of S1 is detected, check the s2GenerationInProgress variable. If it's set (meaning S2 generation is in progress), just exit the ISR without generating S2 again. If it's not set, proceed with S2 generation and set s2GenerationInProgress to indicate that S2 generation is in progress. Completion of S2 Generation: After the main program completes S2 generation, it should clear the s2GenerationInProgress variable to signal that it's done. This approach ensures that the main program and ISR are properly synchronized, and the falling edges of S1 won't interfere with the S2 generation process. If a falling edge of S1 occurs while S2 generation is in progress, the ISR will simply exit without generating another S2. By implementing this synchronization mechanism, you can maintain the integrity of your signal generation process without ignoring any falling edges of S1. -chatgtp
Just a note for your example of stack utilization. Last time I read an ARM book was long time ago and I remember function parameters are passed in registers. If functions take more than 4 arguments, then stack is used as you show in the video. This is why is not advisable to write C functions taking more than 4 values for ARM :D
i have a rising edge interrupt. i'm not even sure it works but when i enable it - while loop breaks. looks as if it goes into interrupt and gets stuck in there in some weird way. but the interrupt pin has never really risen (checked with an oscilloscope). actually i have a message inside the interrupt the interrupt function to notify me that the function was called - it doesn't get called. so if it doesn't goes to interrupt what could mess everything up in such a way? (if i disable interrupt it works normally)
3 роки тому
First just declare the interrupt function fron hal empty. It should work as that. Then try adding back your code and find out where it gets stuck. Also make sure that your priorities are configured. In CubeMX NVIC panel make sure that your interrupt is enabled
Your GPU is running at 60C in idle. That's a common problem with Linux Mint. I think building the newest Kernel should help, since Mint is usually pretty far behind. I had the same problem where Mint showed 60C while in Windows I had only 35C.
3 роки тому+1
The gpu while recording was not in idle because usual idle power draw is 40W and 38C, but here it was almost 90W, so maybe 58C is not that off. Plus I only have one back fan for my case(old workstation). Now I use fedora for work related reasons. Drivers should be more up to date and stable.
Great but calling conventions on ARM typically use some registers to pass arguments, not the stack... that part is rather confusing
Рік тому
That's true. The stack would be used in case of larger arguments or in case you pass a lot. I guess the explanation was a bit simplified and in a way inspired by academic explanations.
Helped me so much to understand the consepts of interrupts and also using them conjugation with sensors. Big thanks!!
Brilliant explanation!
Thank you vary much for sharing this with the community!
Thank you for such informative content
at minute 25:37, you perform an SPI transaction from within an ISR?
Yes. In the use case for the demo, an interrupt for SPI should not block for that long and since the peripherals used inside of the ISR are not used anywhere else in the code, there should be no problem with race register access. It's an isolated case, but not a rare one. I've had a system designed without an RTOS and we used RTC ISR to trigger "precisely" spaced interrupts for sampling SPI ADCs for example. As my work colleague would say: "If you don't measure it, don't poke it". In that case, SPI is quite fast (10Mhz) and it only transfers 16 bits from each sensor, so the whole ISR was quite short and plenty fast for the sampling rate. Context matters and can ease the design.
Excellent tutorial!
Thank you for the valuable content. I would be grateful if you could assist me in answering a question. Regardless of whether the interrupt type is ISR or NVIC, if a falling edge triggers a signal that is going to be sent out through a digital output after a specific delay, and if this delay takes so long that another falling edge occurs at the same time the MCU is sending out that signal, the Interrupt Service Routine will interrupt the main program responsible for sending out the second signal, resulting in the second signal not being sent out as intended. I have already posted this issue on the forum, but I have not received any new information thus far. Does this explanation make sense to you?
Let me summarize your problem so that I can confirm if I understand it correctly.
You have a signal, like an external digital signal, that triggers an interrupt.
That interrupt starts a signal generation, which happens in main. I assume that you have a variable for the communication between interrupt and main.
Main program will wait a set delay amount before signal is generated.
In case, another interrupt arrives, which would create another request to start a signal generation from main, you are worried, that it might be corrupted?
I think I understand your situation or at least I have a few similar scenarios in my head similar to your problem. Can you confirm that?
If so, one answer is that you need to specify the behaviour of the signal generation trigger. You can use another variable, which is written to by main and read by interrupt, which specifies if the main loop is still processing/generating signal. If that's the case, interrupt service routine should just exit, thus ignore the trigger signal.
You can also use the trigger variable as a busy signal. If not set, ISR will set it, maybe do something else. When main reads it, it starts signal generation. If the ISR implementation is so simple, it can just keep setting the trigger signal "to 1" and main won't do anything, since it's still processing the first signal generation. When main is done, it can set the shared signal variable "to 0".
In the case, that you DO do something in the ISR, such as start a timer or any other peripheral, I would strongly suggest adding more status and/or synchronization mechanism either to the interrupt or the main, depending where the most time consuming part is beeing held, like the delay. You can also implement delay as a "state" in the signal generation state machine. With frequent polling you can check the state of the machine.
@ I really appreciate your help, thank you! I'm not sure if I explained the problem as I should. I have a signal (S1) which is coming from an external hall sensor and has the form of a square signal with a frequency of max. 25 Hz. I want to detect the falling edges of this signal a send out another signal (S2) through a DO after a specific delay after every falling edge. So the square signal simply triggers the signal I want to send out. The delay value is going to adjusted through a Potentiometer. The code that specifies the form of S2 is written in the main program. Everything works perfect besides when sending out S2 by the main interferes with a new falling edge of S1 which is detected by the ISR. When this happens the S2 starts behaving like it's triggered by the falling edge anymore. The Problem is that I'm not allowed to ignore any of the falling edges. So if put a variable that checks if the main is still sending out S2 and just exit the ISR when it's the case I assure that new falling edge will be "ignored".
@@ezz6928 I understand your issue more clearly now. You have an external signal (S1) triggering an interrupt to generate another signal (S2) with a specific delay, and you can't ignore any of the falling edges of S1. When the main program generates S2, it interferes with a new falling edge of S1, causing unexpected behavior in S2.
To address this issue, you can implement a more robust synchronization mechanism between the main program and the interrupt service routine (ISR). Here's a possible approach:
Shared Variable: Create a shared variable, let's call it s2GenerationInProgress, which will be used to indicate whether the main program is currently generating S2.
Main Program:
Before starting the S2 generation process, check the s2GenerationInProgress variable.
If it's set (meaning S2 generation is in progress), wait until it's cleared before proceeding.
Once it's cleared, set s2GenerationInProgress to indicate that the main program is now generating S2.
Generate S2 as planned.
ISR:
When the falling edge of S1 is detected, check the s2GenerationInProgress variable.
If it's set (meaning S2 generation is in progress), just exit the ISR without generating S2 again.
If it's not set, proceed with S2 generation and set s2GenerationInProgress to indicate that S2 generation is in progress.
Completion of S2 Generation:
After the main program completes S2 generation, it should clear the s2GenerationInProgress variable to signal that it's done.
This approach ensures that the main program and ISR are properly synchronized, and the falling edges of S1 won't interfere with the S2 generation process. If a falling edge of S1 occurs while S2 generation is in progress, the ISR will simply exit without generating another S2.
By implementing this synchronization mechanism, you can maintain the integrity of your signal generation process without ignoring any falling edges of S1. -chatgtp
Magnificent video dude, can you explain how to calibrate an accelerometer?. Regards from Argentina.
Thank you. I have other topics in line that would go well with peripheral topics more. I'll keep it in mind.
Just a note for your example of stack utilization. Last time I read an ARM book was long time ago and I remember function parameters are passed in registers. If functions take more than 4 arguments, then stack is used as you show in the video. This is why is not advisable to write C functions taking more than 4 values for ARM :D
I agree with you, thank you for pointing it out.
@ keep them coming I'm viewing your videos because I was laid off and need to brush up my concepts :D
Bravo! Thank you 🙏
i have a rising edge interrupt. i'm not even sure it works but when i enable it - while loop breaks. looks as if it goes into interrupt and gets stuck in there in some weird way. but the interrupt pin has never really risen (checked with an oscilloscope). actually i have a message inside the interrupt the interrupt function to notify me that the function was called - it doesn't get called. so if it doesn't goes to interrupt what could mess everything up in such a way? (if i disable interrupt it works normally)
First just declare the interrupt function fron hal empty. It should work as that. Then try adding back your code and find out where it gets stuck. Also make sure that your priorities are configured. In CubeMX NVIC panel make sure that your interrupt is enabled
very informative ..thanks
Your GPU is running at 60C in idle. That's a common problem with Linux Mint. I think building the newest Kernel should help, since Mint is usually pretty far behind.
I had the same problem where Mint showed 60C while in Windows I had only 35C.
The gpu while recording was not in idle because usual idle power draw is 40W and 38C, but here it was almost 90W, so maybe 58C is not that off. Plus I only have one back fan for my case(old workstation).
Now I use fedora for work related reasons. Drivers should be more up to date and stable.
@ Ah, it's a desktop? The problem afaik is only present on laptops with two gpus (ie. intel + nvidia).
Great but calling conventions on ARM typically use some registers to pass arguments, not the stack... that part is rather confusing
That's true. The stack would be used in case of larger arguments or in case you pass a lot. I guess the explanation was a bit simplified and in a way inspired by academic explanations.
Toooooo much talking !!!!!!!
That's the way the script for the video was written, as intended.
Toooooo short attention span !!!!!!!!!!
@ excellent video, thank you Matej 🙏