In this code I have not used while(1), only when it enters 'if' condition it calls TIMER_ISR function which has been initialised for every 250ms. But when it enters else condition there is no any timer function or anything but then also why it is running continuously.
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/eusart1.h"
void main(void)
{
SYSTEM_Initialize();
INTERRUPT_GlobalInterruptEnable();
INTERRUPT_PeripheralInterruptEnable();
char temp1[] = "ok";
char temp2[3] = { '\0', '\0', '\0' };
char temp3[3], temp4[3];
int i, j;
for (i = 0; temp1[i] != '\0'; i++)
{
temp3[i] = temp1[i] - 32;
EUSART1_Write(temp3[i]);
}
EUSART1_String("\r\n");
for (i = 0; i < 2; i++)
{
temp2[i] = EUSART1_Read();
EUSART1_Write(temp2[i]);
}
EUSART1_String("\r\n");
if (strcmp(temp1, temp2) == 0)
{
for (i = 0; temp1[i] != '\0'; i++)
{
if (temp1[i] >= 'a' && temp1[i] <= 'z')
{
temp1[i] = temp1[i] - 32;
}
}
for (j = 0; temp1[j]; j++)
EUSART1_Write(temp1[j]);
//Timer initialization (timer is initialized for every 250mS)
TMR0_Initialize();
}
else
EUSART1_String("\r\nERROR GIVE'ok'");
}
In case the question is: does it make sense to return from main() on a bare metal MCU application, then TL;DR: No it doesn't make sense because there is nobody to return to. No OS to hold your hand - your application is all there is.
Detailed explanation:
All modern MCUs have a point of entry called "reset interrupt". Where you can end up when you get a power-on, or perhaps after a watchdog circuit has reset the MCU, or because you have an external /reset signal on the MCU reset pin.
The program counter then starts the program by entering the interrupt service routine for power-on reset (sometimes called reset vector). From here on, the most basic stuff on the MCU are set, then typically it will call a "C run-time" (CRT), which is compiler-specific start-up code for the purpose of initializing all memory regions to enable a standard C environment, such as initializing variables etc. When the CRT is done with all that, it calls main().
Or in case you wrote everything in assembler, you wouldn't have to bother with the CRT but can call whatever function you like from the reset ISR. Often this is done with a direct jump instead of a function call, without stacking any parameters, because you don't expect to ever return. You'd only waste stack space needlessly.
That's why the most common form of main() in embedded systems is void main (void), rather than the strictly C conforming int main (void) - the latter may waste space on the stack needlessly due to calling convention. (On the gcc compiler, always pick embedded "freestanding" systems as your target with -ffreestanding.)
Now if you wrote the program in C and were to return from main(), you will at best crash back out into the CRT code, where if you are lucky, some kind person wrote a for(;;){} loop there to catch the program counter. This is common with rookie-friendly environments. Alternatively you could crash all the way back out to the power-on reset ISR.
Or more likely, in case main() was called the assembler way described above (either from the CRT or from your custom code) you jump straight into the unknown since no return address was saved.
From there, the program counter will run out in random memory locations, starting to execute whatever it comes across next in the memory it ends up, interpreting the contents of those cells as OP codes, whether they are that or not - you get "runaway code", which is a severe and dangerous bug condition. It will keep doing this either until it stumbles upon something that causes a hardware exception, like accessing protected memory, or until the watchdog resets everything, in case the watchdog is enabled.
Related
I am currently having trouble getting interrupt handlers to work in C. The idea with my code is to set a vector to IRQ 0, which is the PIT, and from what I can find is interrupt 8 (0x08), after setting the PIT to operate on about 40hz (which from what I can find this is by setting a value of 29829, or 0x7485.
The final intended result of the program is to count to a second, print something to screen, and then repeat that 20 times, at which point it uninstalls itself.
This program was compiled using Borland's Turbo C on an Am486-DX4-100 running at 120mhz with IBM's PC-DOS 2000. The board is the Socket 3 EXP-4045 by DataExpert, but I have the same results on DOSBox.
Here is the code:
#include <dos.h>
#include <stdio.h>
int a = 0;
int b = 0;
void interrupt clocktick(){
if(a == 40){
if(b == 20){
setvect(8, NULL);
}else b++;
}else a++;
}
int main(void){
/* set PIT mode*/
outp(0x34, 0x43);
outp(0x85,0x40); /* send low byte*/
outp(0x74,0x40); /* send high byte*/
setvect(0x08, clocktick);
while(1==1){
printf("a%i, b%i", a, b);
}
getchar();
return 0;
}
The code compiles fine, and when ran, the while look does show that A has been incremented once, but doesn't fire again. Obviously something is generating an interrupt, and it may even be the PIT, but it's not doing it more than once.
I am trying to follow the 1987 user's manual for Turbo C, which tries to describe the method for installing interrupt vectors, but I've obviously done something wrong.
I also need to say I am sorry for not knowing this stuff. I don't mean to waste people's time, but I am in genuine need of a helping hand. My examples were vauge, and after some comments I do see there is stuff I could have done to try to figure out what was going on.
You'd need to tell the PIC that you've finished handling the interrupt, otherwise it won't signal it again. Typically this is done by sending an EOI (0x20) to the PIC base port (0x20), so it would essentially be something like outportb(0x20, 0x20);, preferably near the end of your handler.
There's some information about the PIC at e.g. https://wiki.osdev.org/8259_PIC
I am a newbie with programming and I am having trouble getting my interrupts to work the way I want them to for my application. I want to send serial data over the UART to the PSoC, store the values every second, and then echo back the stored values. I am using a RX interrupt (RX FIFO not empty, priority 2) and a timer interrupt with the TC (priority 3). Attached is the TopDesign configuration. Currently, I am trying to get this code to work (just a sample code to see if I can get the interrupts to work correctly). I send the PSoC a string containing a character 'o', I should be reading only 'o' and '-', but the code always gets stuck in one of the interrupts with the other one never working. Could anyone tell me what I am doing incorrectly? Much appreciated!
The board is CY8CKIT-042.
#include <project.h>//Contains
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
uint16 ms_count = 0;
uint8 ch;
CY_ISR_PROTO(Timer_ISR);
CY_ISR_PROTO(RX_ISR);
CY_ISR(Timer_ISR){//Every millisecond, the code goes here
ms_count++;
if (ms_count == 1000){//Every second
ms_count = 0;
LED_Write(!LED_Read());
while(ch != 'o')UART_UartPutChar('-');
}
}
CY_ISR(RX_ISR){
uint8 status = UART_rx_ClearInterrupt();//Clear interrupt flag
uint8 sub;
sub = UART_UartGetChar();
if (sub != 0u){//Make sure grabbed character is not an empty
ch = sub;
if (ch == 'o'){
UART_UartPutChar(ch);
}
}
}
int main()
{
/* Start SCB UART TX+RX operation */
Timer_1_Start();
Time_ISR_StartEx(Timer_ISR);
RX_ISR_StartEx(RX_ISR);
CyGlobalIntEnable;
/* Start SCB UART TX+RX operation */
UART_Start();
UART_UartPutString("fdssf\n");
for(;;)
{
}
}
I want to send serial data over the UART to the PSoC, store the values every second, and then echo back the stored values. I am using a RX interrupt (RX FIFO not empty, priority 2) and a timer interrupt with the TC (priority 3).
One important principle for interrupt service routines (ISR's) is to make them as short as possible. Another is to make sure they don't block. As pointed out by Hans Passant in the comments, your Timer_ISR is blocking with the while loop. It's going to continually spam putting the '-' character into the UART and not allow anything else to happen. That's a bad idea. IMHO, enabling nested interrupts isn't really a good idea here.
It actually looks like you're already echoing the character 'o' with this line:
if (ch == 'o'){
UART_UartPutChar(ch);
}
You aren't actually waiting a second to echo back the 'o' here, it's happening immediately. You can simply add UART_UartPutChar('-') inside that if statement to also send the dash character immediately. It sounds like you're writing a simple test application for now just to get things working, and I wouldn't bother waiting until the timer ISR fires off to echo back the 'o' or the '-' for a simple test application.
Alternatively, if you only want to print the dash once per second if the letter 'o' is the most recently read letter, you can replace the while loop with a simple if statement:
if(ch == 'o')UART_UartPutChar('-');
Keep in mind that would only work if 'o' was the most recently read character, since you're overwriting the ch variable with every new character read (including new lines). I'm not sure what purpose that would serve, but there it is.
Something you might consider in the future when using ISR's is letting an ISR set a flag and having the main loop watch for that flag and then do something to react to it, for example:
volatile int flag = 0;
CY_ISR(Timer_ISR){//Every millisecond, the code goes here
if (some event) {
flag=1;
}
void main() {
while (1) {
if (flag) {
flag=0;
do_something_in_a_long_loop();
}
}
}
(Read more about volatile here).
This is only one way of approaching this problem of long loops. Also, whether you want to clear the flag before or after the long block of code depends on your application. This does have the (very likely) potential of missing events if your block of code is too long and the events come too frequently. In that case, it may be a good idea to start use threading or real-time operating systems. How you design your program obviously depends on the problem that you're solving.
A word of warning: when sharing global variables between ISR's and main code, or when dealing with multi-threaded applications, it's very easy to run into race conditions. You need to be aware of these potential pitfalls and the various strategies for dealing with them properly. I'd suggest picking up a book or taking a class about embedded programming and/or real-time operating systems. Welcome to the very complex world of embedded and real-time programming!
Consider the following snippet of C code:
int flag = 0;
/* Assume that the functions lock_helper, unlock_helper implement enter/leave in
* a global mutex and thread_start_helper simply runs the function in separate
* operating-system threads */
void worker1()
{
/* Long-running job here */
lock_helper();
if (!flag)
flag = 1;
unlock_helper();
}
void worker2()
{
/* Another long-running job here */
lock_helper();
if (!flag)
flag = 2;
unlock_helper();
}
int main(int argc, char **argv)
{
thread_start_helper(&worker1);
thread_start_helper(&worker2);
do
{
/* doing something */
} while (!flag);
/* do something with 'flag' */
}
Questions:
Is it it possible that 'flag' will always be 0 for the main thread(and it
becomes stuck in the do/while loop) due to some compiler optimization?
Will the 'volatile' modifier make any difference?
If the answer is 'depends on a feature provided by the compiler', is there any
way I can check for this 'feature' with a configuration script at
compile-time?
The code is likely to work as is, but is somewhat fragile. For one thing, it depends on the reads and writes to flag being atomic on the processor being used (and that flag's alignment is sufficient).
I would recommend either using a read lock to read the value of flag or use functionality of whatever threading library you are using to make flag properly atomic.
Since you can assume that the loading of an aligned int is an atomic operation, the only danger with your code is the optimizer: your compiler is allowed to optimize away all but the first reads of flag within main(), i. e. to convert your code into
int main(int argc, char **argv)
{
thread_start_helper(&worker1);
thread_start_helper(&worker2);
/* doing something */
if(!flag) {
while(1) /* doing something */
}
//This point is unreachable and the following can be optimized away entirely.
/* do something with 'flag' */
}
There are two ways you can make sure that this does not happen: 1. make flag volatile, which is a bad idea because it includes quite a bit of unwanted overhead, and 2. introduce the necessary memory barriers. Due to the atomicity of reading an int and the fact that you only want to interprete the value of flag after it has changed, you should be able to get away with just a compiler barrier before the loop condition like this:
int main(int argc, char **argv)
{
thread_start_helper(&worker1);
thread_start_helper(&worker2);
do
{
/* doing something */
barrier();
} while(!flag)
/* do something with 'flag' */
}
The barrier() used here is very lightweight, it is the cheapest of all barriers available.
This is not enough if you want to analyze any other data that is written before flag is raised, because you might still load stale data from memory (because the CPU decided to prefetch the value). For a comprehensive discussion of memory fences, their necessity, and their use, see https://www.kernel.org/doc/Documentation/memory-barriers.txt
Finally, you should be aware, that the other writer thread may modify flag at any time after the do{}while() loop exits. So, you should immediately copy its value to a shadow variable like this:
int myFlagCopy;
do
{
/* doing something */
barrier();
} while(!(myFlagCopy = flag))
/* do something with 'myFlagCopy' */
It is possible that the while is executed before the threads... you have to wait the execution of thread before, using pthread_join()
In the following piece of code, what does *(int32 *) 0 = 0; mean?
void
function (void)
{
...
for (;;)
*(int32 *) 0 = 0; /* What does this line do? */
}
A few notes:
The code seems to not be reachable, as there is an exit statement before that particular piece of code.
int32 is typedef'ed but you shouldn't care too much about it.
This piece of code is from a language's runtime in a compiler, for anyone interested.
The code is doing the following:
for (;;) // while(true)
*(int32 *) 0 = 0; // Treat 0 as an address, de-reference the 0 address and try and store 0 into it.
This should segfault, null pointer de-reference.
EDIT
Compiled and ran for further information:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(void){
*(int32_t *) 0 = 0;
printf("done\n");
return 0;
}
gcc -g null.c; ./a.out
Program received signal SIGSEGV, Segmentation fault.
0x00000000004004cd in main () at null.c:7
7 *(int32_t *) 0 = 0;
Since the OP states the code was written by experienced compiler engineers, it is possible this is the intent of the code:
*(int32 *) 0 = 0; is recognized by this specific C implementation as code that causes behavior not defined by the C standard and known to this implementation to be illegal.
The for (;;) additionally indicates that this code is never exited.
The compiler engineers know that the optimizer will recognize this code and deduce that it may be “optimized away”, because any program that reaches this code is permitted to have any behavior, so the optimizer may choose to give it the behavior as if the code is never reached.1
This sort of reasoning is possible only if you have specific knowledge of the internal operation of a C implementation. It is the sort of thing a compiler engineer might include in special headers for a C implementation, perhaps to mark that certain code (such as code after an abort call) is never reached. It should never be used in normal programming.
1 For example, consider this code:
if (a)
for (;;)
*(int 32 *) 0 = 0;
else
foo();
The compiler can recognize that the then-clause is permitted to have any behavior. Therefore, the compiler is free to choose what behavior it has. For simplicity, it chooses it to have the same behavior as foo();. Then the code becomes:
if (a)
foo();
else
foo();
and can be further simplified to:
foo();
In fact that this code seg-faulting doesn't explain why it's exists =)
I think that's from runtime of some MCU.. and reason it is there because if program execution will get to this point such instruction will either initiate software reset for an MCU, so program will be restarted (which is common practice in embedded development) OR if MCU configured with hardware watchdog, force MCU restart because of hardware watchdog and never ending loop.
Main goal of such constructions to invoke an interrupt which can be handled either by OS or by hardware for initiate certain actions.
Knowing that its x86 it will depend on a CPU mode... in Real Mode nothing will really happened instantly if there is no watchdog, at address 0 there is an address of 'divide by 0' handler, so if it's some old MS-DOS or embedded x86 runtime it will change an address of the 'Divide by 0' handler to 0, so as soon as it happens and this interrupt is not masked CPU will jump to location 0:0 and probably will just restart because of illegal instruction.. if it's protected or VM x86 code then it's a way to notify OS or any other supervisor that there is a problem in runtime and software should be 'killed' externally.
for(;;) is equivalent to while(1),
*(int32 *) 0 = 0;writes 0 to a dereferenced null pointer, which is expected to cause a crash, but actually won't at all times on certain compilers: Crashing threads with *(int*)NULL = 1; problematic?
It's an infinite loop of undefined behavior (dereferencing a null pointer). It's likely to crash with a segfault on *n*x or Access Violation on Windows.
Mike's comment is pretty well correct: it's storing the VALUE zero at the ADDRESS 0.
Which will be a crash on most machines.
The original IBM PC stored the interrupt vector table in the lowest 1 KiB of memory. Hence actually writing a 32-bit value to the address 0 on such an architecture would overwrite the address for INT 00h. INT 00h looks unused in the PC.
On basically anything modern (meaning in x86/x86-64 parlace anything running in protected or long mode), it will trigger a segmentation fault unless you are in ring 0 (kernel mode) because you are stepping outside of your process' allowed address dereference range.
As the dereference is undefined behavior (as already stated), a segmentation fault is a perfectly acceptable way to handle that situation. If you know that on the target architecture a zero address dereference causes a segmentation fault, it's seems to be a pretty sure way to get the application to crash. If exit() returns, that's probably what you want to do, since something just went horribly wrong. That the code is from a particular compiler's runtime means whoever wrote it can take advantage of knowledge of the internal workings of the compiler and runtime, as well as tailor it to the specific target architecture's behavior.
It could be that the compiler doesn't know exit() doesn't return, but it does know this construct does not return.
I wrote a segmentation fault handler but the problem is, the instruction at which the fault is happening is restarted after going to the handler, and this causes the handler to go to infinite loop.
I want the handler to work such that after reaching the handler, the instruction following the faulty instruction should be executed such that it does not go to infinite loop. Can anyone please help me with some code snippet?
I am using C and Linux.
Warning: I do not recommend doing this. Listen to the comments telling you to find some other way to solve you problem
I'd also like to re-iterate Henning Makholms warning that it will be extremely architecture-specific and nonportable. It will be maintenance hell and you will have to manually handle lots of different instructions unless it is one specific instruction sequence you're looking for (as in the below example).
With that said if you still want to do it, it can be done in the following manner:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <time.h>
#define __USE_GNU
#include <signal.h>
void action(int sig, siginfo_t* siginfo, void* context)
{
sig=sig; siginfo=siginfo;// ignore warning
// get execution context
mcontext_t* mcontext = &((ucontext_t*)context)->uc_mcontext;
// find out what instruction faulted
#if defined(__x86_64)
uint8_t* code = (uint8_t*)mcontext->gregs[REG_RIP];
if (code[0] == 0x88 && code[1] == 0x10) { // mov %dl,(%rax)
mcontext->gregs[REG_RIP] += 2; // skip it!
return;
}
#elif defined(__i386)
uint8_t* code = (uint8_t*)mcontext->gregs[REG_EIP];
if (code[0] == 0x88 && code[1] == 0x10) { // mov %dl,(%eax)
mcontext->gregs[REG_EIP] += 2; // skip it!
return;
}
#else
#error "Unsupported system"
#endif
// unknown/unhandled instruction failed...
// only for debugging, shouldn't print stuff in a signal handler
int i = 0;
for (i = 0; i < 16; i++) {
fprintf(stderr, "%2.2X ", code[i]);
}
fprintf(stderr, "\n");
exit(1);
}
int main(void)
{
// install SIGSEGV handler
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_sigaction = action;
act.sa_flags = SA_SIGINFO;
if (sigaction(SIGSEGV, &act, NULL) < 0) {
perror("sigaction");
return 1;
}
// cause fault
int i;
for (i = 0; i < 10; i++) {
((unsigned char*)0)[i] = i;
}
return EXIT_SUCCESS;
}
Here I have only handled one specific instruction sequence for x86 32- and 64-bit, though it should be trivial (if tedious) to support more architectures and instructions.
Update: You (now) mention that you are on an ARM machine. That should actually make it easier as the instructions are always 32-bit (except in thumb mode) if I'm not mistaken. I don't have an ARM machine to test this one, so you will have to dig into sys/ucontext.h to check if I got the names right. Ofcourse you should also be checking the faulting instruction in a similar fashion. My best guess as to how it is for ARM is the following (placed along side the other #if defined(...) statements:
#elif defined(__arm) // or use what your GCC defines, also check for 32-bit arm mode or whatever...
uint8_t* code = (uint8_t*)mcontext->arm_pc;
if (*(uint32_t*)code == /*some instruction*/) {
mcontext->arm_pc += 4; // skip it!
return;
}
Simply skipping a failing instruction sounds like a recipe for extremely hard-to-track-down errors. However, if you really want to, you can rewrite the IP in the ucontext struct the handler gets as a second or third (I forget which, but don't try any of this without reading the manpages closely anyway) parameter. You'll need to disassemble the faulting instruction for yourself in order to find out how long it is -- which is good because you shouldn't be skipping instructions that you don't understand.
Whatever you do, the result will be extremely architecture-specific and nonportable.
I have figured out an alternate and perhaps easier way to write a segmentation fault handler. Although user78863 answer and effort is praiseworthy, but seeing the complexity of code and difficult in porting, i think my solution is better. So i will accept my answer.
Here is the link to the code: Can we reset sigsetjmp to return "0" again (Reset sigsetjmp)?