Disclaimer: This article is an original work and copyright belongs to the author of this blog.All. If you need to repost, please indicate the sourceHttp://www.cnblogs.com/kingst/
Introduction
In this section, we will explain the hardware interruption of the niosii. We will also introduce the methods and techniques for online debugging of the niosii IDE. First of all, I would like to introduce some theoretical knowledge about hardware interruptions, so that you can have a general understanding of hardware interruptions of niosii.
ISR (interrupt service routine) interrupt service function is a sub-module of hardware interrupt service.Program. The NiO II processor supports 32 hardware interruptions. Each enable hardware interrupt should correspond to an ISR. When an interruption occurs, the hardware interrupt processor calls the corresponding ISR to interrupt the service based on the detected valid interrupt level.
To complete hardware interruption, we need to do two things:
First, register the interrupt function ISR. Its function prototype is as follows:
Int alt_irq_register (alt_u32 ID, void * context, void (* Handler) (void *, alt_u32 ));
ID: the interrupt priority, that is, the registered ISR indicates the interrupt priority of the service. We mentioned the interrupt priority in the Part 1 builder. If you do not know whether you remember it, Let's recall it, as shown in. In this step, we can automatically allocate the interrupt.
Shows the allocated IRQ. Of course, you can manually modify the IRQ according to your special requirements. It is okay if it is not repeated.
However, the system is embodied in the nioii ide software. in the H file, we also mentioned it before, as shown in. See it. jtag_uart_irq is 0, which is exactly the same as the interrupt number. This is not a coincidence. As I have already said, the system. h file is generated based on the soft core, so it is conceivable that jtag_uart_irq is equal to 0.
Next we will continue to talk about the remaining two parameters,
Context, which is a registered ISR parameter. It can be null;
Handler, the pointer to the ISR function that interrupts the service.
Return value. If the return value is 0, the registration is interrupted successfully. If the return value is negative, the registration fails.
There is a place to register. If handler is not null, the priority interruption will be automatically enabled after the registration is successful. That is to say, as long as we have an ISR at the handler, we do not need to proceed with the operation. Speaking first, let's talk about second.
Second, write the ISR function, which we can write on our own, rather than provided by the Hal system. It is no different from the general function definition, but has specific requirements on the ISR function prototype:
Void isr_handler (void * context, alt_u32 ID );
Context: The input parameter passed to ISR. It can be null;
ID: interrupt priority.
OK. We can complete the process of the interrupt function in these two steps. Let's just talk about it. Come with me.
Hardware development
Next, we will use an external button to verify the processing process of the interrupt function.
First, we need to construct a PIO module for external buttons. I have already discussed this part in detail. I 'd like to explain it briefly here.
Open the Quartus II software, and double-click the kernel to go To the FPGA builder. After entering, we will create a PIO module, and there is a difference in the creation process. Let's take a look, as shown in, at Red Circle 1, we enter 1, because we only need one button (five buttons in the black gold Development Board), and input ports only is selected for the red circle 2. Click Next,
As shown in, we select general IRQ. There are two types of interruptions: Level interruption, high-level or low-level interruption, and edge interruption, including the rising and falling edges. People who have done single-chip microcomputer should be familiar with it. If you want to achieve edge interruption, You need to select the Red Circle 1 (synchronously capture). The following three methods are available, you can select one based on your requirements. After completing the above work, click Finish to complete the PIO build.
You need to modify the name below. I will name it key, as shown in red circle 1. Let's take a look at the red circle 2. We can find that there are two 0 interrupt numbers, one is jtag_uart and the other is our new key. This time we understand, why do we need to allocate the interrupt number automatically? The same interrupt priority has emerged.
Next, we will automatically allocate interruptions. As shown in, we can see that there has been a change in the red circle 2, and the interruption level of the key has changed to 1. Automatic interrupt allocation is distributed from bottom to bottom in order.
After completing the above Build, compilation started, and it took a long time to wait ...... (It's not very long, just a minute or two, depending on the computer configuration)
After compilation, return to the Quartus interface and sort it out. Add the key input pin. I will skip it briefly here. Let's take a look at the future. As shown in, I name it key [4], which corresponds to the key in the middle of my black gold Development Board. Note that when the level is interrupted, you must add a non-gate if you want to achieve low-level sensitivity,
The method for adding a non-portal is the same as adding an input pin. Double-click the blank space and enter not in the red circle. Click OK.
Then, assign pins, compile, and wait ......
After compilation, let's look at how many resources are used, as shown in, or 66%,
Let's make a comparison. In the previous section, we used resources, as shown in.
After comparison, it is found that the PIO module occupies a considerable amount of resources.
After compilation, you can download the Code either in the as mode or in the JTAG mode. However, remember that the JTAG mode will be lost when power loss occurs. Remember to re-run the code after power-on.
The hardware part is over. Let's talk about the software programming part.
Software Development
Open the niosii 9.0 ide software and compile it once. The shortcut key is Ctrl + B (I prefer the shortcut key, which is convenient and convenient ). After compilation, let's take a look at the changes in system. h. As you can see, system. h has the following content, which is related to the key, where red circle 1 is the base address and red circle 2 is the interrupt number, which we will use below, first, let's get an impression.
Next, we will start to write the program. First, we need to add the content in the system. H, as shown in, which is the same as the led in the previous section, so we will not explain it here.
After modification, we. the C function is changed. As shown in the overall program, this program does not perform anti-shake processing on the buttons, just to demonstrate the operation process of External Interrupt Processing. to be used as a project application, you must add the anti-shake processing button, it is not described here. This function is interrupted by pressing an external button, because we set the low level to interrupt, so when the button is pressed, a low level will be generated, and the interrupt function will be entered. In the interrupt function, we reverse the key_flag. In the main function, we constantly query. When the key_flag is 1, the LED-> data is set to 1, that is, to enable the external light emitting diode; when the key_flag is 0, LED-> DATA 0, then the light emitting diode is not on.
Next we will explain each function in detail.
First, compile an initialization program, as shown in. There are two statements in total. let's first talk about the statement in red circle 1. The purpose of this statement is to enable the interrupt bit. I have already discussed it in the previous section, interrupt_mask In the struct corresponding to the PIO module is the memory ing of the interrupt control register. When this position is 1, interruption is allowed. Otherwise, interruption is prohibited. Again, we have already seen the statement at red circle 2 and used it to complete interrupt registration. key_irq comes from system. H, and isr_key is the ISR function. Return is used to determine whether the registration is successful in the main function. If the registration is successful, 0 is returned. If the registration is not successful, the registration fails.
Next let's take a look at the isr_key function. As shown in, there is only one statement. In this statement, key_flag is a global variable. If there is no interruption, the key_flag is reversed.
The following is the main function. In the Red Circle, 1 is used to determine whether the initialization is successful. If the return value of init_key () is 0, the registration is successful and the register successfully is printed! \ N, you can see it in the observation column, otherwise print error: Register failure! \ N. Red Circle 2 is to judge the flag key_flag. If it is 1, set led-> data to 1, that is, to make the corresponding LED light, otherwise the LED will not light up.
This program is very simple, which helps us to understand the interrupt processing process.
Now, let's take a look at the opportunity of interruptions to introduce how to conduct online debugging (Debug) in the niosii IDE ). As shown in, right-click hello_world on the Left Border, select debug as-> nioii hardware, or press the shortcut key F11 (prerequisite: the simulator is connected to the JTAG port and the power supply is powered on ), the debug page is displayed.
Let's briefly introduce several functional columns on the debug interface,CodeArea is not required. Show ourSource codeThe observation area mainly uses two modules: console and memory. Memory cannot be used in normal mode. That is to say, only in debug mode can we use memory to observe the changes in memory values. The variable area is mainly used to observe the value of a variable. Its existence helps us determine whether the change of a value is the same as we expected. There are also some function keys that are frequently used during debugging. Including start, stop, and single-step debugging function keys in three modes. Other regions also have certain functions. You can study the functions by yourself, which is helpful for debugging programs.
After briefly introducing some features, let's debug our interrupt program. For debugging interrupt programs, we have a simple and effective method to determine whether the interrupt enters.
First, set a breakpoint in the interrupt function. You can set the breakpoint by right-clicking the place where you need to set the breakpoint, that is, the red circle.
Write down, let the program run at full speed, and press the button in the red circle. After the program runs, press the external button on the Development Board (the button in the middle). If there is no problem with the interruption, the program will stop at the interrupt point we set. This indicates that the interruption is successful. Even if this method is easy to use, it is very good for debugging to interrupt such programs.
I won't say much about how to use single-step debugging and other functions as long as I have played single-chip microcomputer.
Summary
Finally, let's briefly summarize the notes for interruptions. As we all know, the interrupt program mainly handles some operations with strong real-time performance, so it is not possible to perform wait or obstructive operations in the interrupt program. Therefore, try to keep the interrupt service program streamlined and avoid complicated processing in the interrupt program, such as floating-point operations and printf functions.
This section ends. Due to the rush, there may be problems with the content. I hope you can point out that I will modify it.