標題: NIOS II 9.1 SP1中斷問題 [打印本頁]
作者: 51黑fan 時間: 2016-1-31 04:17
標題: NIOS II 9.1 SP1中斷問題
本帖最后由 51黑fan 于 2016-1-31 04:19 編輯
首先NIOS 91用了增強型中斷,當然這不是問題的關鍵,我不詳說,看牙縫的博客
debug 進了中斷n次看細節,無奈真想砸電腦,下面是alt_ic_arq_register() 原型以及內部的int alt_irq_register,我不知道為什么這就是所謂的增強型,聽說是為了便于以后升級:
int alt_ic_isr_register(alt_u32 ic_id, alt_u32 irq, alt_isr_func isr,
void *isr_context, void *flags)
{
return alt_irq_register(irq, isr_context, isr);
}
int alt_irq_register (alt_u32 id,
void* context,
alt_isr_func handler)
{
int rc = -EINVAL;
alt_irq_context status;
if (id < ALT_NIRQ)
{
/*
* interrupts are disabled while the handler tables are updated to ensure
* that an interrupt doesn't occur while the tables are in an inconsistant
* state.
*/
status = alt_irq_disable_all ();
alt_irq[id].handler = handler;
alt_irq[id].context = context;
rc = (handler) ? alt_irq_enable (id): alt_irq_disable (id);
alt_irq_enable_all(status);
}
return rc;
}
在群里大俠的幫助下,還是NND的不行。。。在與牙縫和o my god的共同協作下,還是不行。。;枇
最后不小心試試看是不是多路除了問題,然后單路,竟然可以了,回過頭去看SOPC,發現剛好忘了選擇Enable bit_clearing。。。這樣就行了。
昏,知其然,不知道其所以然,尋找問題的答案。!于是和我師父分析為什么???師徒兩解決了n久n久,終于解決了師父一年前的問題以后我此刻最難受的郁悶:都是Eanbel bit_clearing惹的禍:
意思是說:
Bit n 在邊沿捕獲寄存器中,如果捕獲了輸入(相應的上升沿,下降沿),相應位的位就會被置1 。一個阿窩龍妹妹外設可以讀取邊沿捕獲寄存器,來決定發生在PIO引腳的邊沿變化。 如果選項“Enable bit_clearing for edge capture register”被關閉,寫任意的值到邊沿捕獲寄存器將會清除所有寄存器。反之,寫一個1到寄存器中一個特別的位,將會使得邊沿捕獲失去作用。
根據我的實際測試,驗證了以上的一些理論
(1)Enable bit_clearing 打開的時候:
因為ds說1 的時候清中斷,所以IOWR_ALTERA_AVALON_PIO_EDGE_CAP(KEY_DATA_BASE, 0x03);清了我兩個按鍵的中斷,問題成功解決。
(2)Enable bit_clearing 關閉的時候:
因為ds說任意值寫入都將會清除所有的邊沿捕獲寄存器,所以IOWR_ALTERA_AVALON_PIO_EDGE_CAP(KEY_DATA_BASE, any vaule);都能使得edgecapture清零,實際測試用了“IOWR_ALTERA_AVALON_PIO_EDGE_CAP(KEY_DATA_BASE, 0x00);”和“IOWR_ALTERA_AVALON_PIO_EDGE_CAP(KEY_DATA_BASE, 0x03);”,都達到了效果。當然習慣性的我們會用0來清零,以至于讓人再次產生了誤解。
可是明擺著這些都能達到目的嘛,altera為啥要搞得那么尷尬呢??有必要嗎???
根據我師父的解釋,解釋如下:
(1)在一般情況下,外部中斷不會同時達到,因此bit_clearing顯得沒有什么意義,比如我們捕獲按鍵,那個按下就讓那個LED亮,同時按下就同時亮,這個完全沒問題,直接IOWR_ALTERA_AVALON_PIO_DATA(LED_DATA_BASE, edge_capture);嘛。!
(2)但是這不否決中斷同步捕獲的情況。當中斷同步捕獲的時候,可以用bit_clearing來干活了,也許可以更加的靈活。因為中斷同時達到的時候,PIO當然能夠同時捕獲兩個中斷信號,但是此時main()函數里面的執行就很尷尬了,兩個中斷到底聽誰的呢?(你爸媽一個讓你幫他做飯,一個讓你陪他下棋,媽的老子聽誰的,不干了繼續玩NIOS2。
這相當于verilog中的異步,需要同步處理之后才OK)。因此利用bit_clearing來屏蔽同時捕獲中斷的位,下一次再屏蔽另一個來讓CPU執行命令,給CPU完成一個該聽誰的機會,這樣也能有效防止CPU死機(TMD老子不干了)。
因為PIO IRS這個在SOPC中指分配了一個IRQ,所以無所謂單片機中的“中斷優先級”的說法,所以只能通過bit_clearing來更完美的分配CPU 的任務。
以上說明基本上解釋了以下ZLG的翻譯是錯了,以前我也對著ds發現過別的error,看來原汁原味的dt就是好!
最后解釋一個為什么在Enable bit_clearing 打開的時候,IOWR_ALTERA_AVALON_PIO_EDGE_CAP(KEY_DATA_BASE,0x00)為什么會死機,程序卡死在初始化這句話中的問題:
根據altera的dt(我以上分析的(2)),講到了當打開Enable bit_cleraing的時候,要給相應位寫1,才能清除標志位。(網上很多人都是給0清零的,這可能是因為他們沒有打開Enbale bit_clearing),但是我們給了0 來清楚edagcapture,這樣根本不能清除中斷標志,因此一次死在里面(所謂君讓臣死,臣不得不死,不死也得死)。只有清除了才可以,根據我的驗證,此時寫1來清除相應的bit,很好的解決了問題。
. 問題到了現在算是比較清晰了,還以為ALtera自己神經病,最后發現不是軟件問題,也不是altera神經病,而是我們沒有好好啃ds。
師父說:“altara是奧特拉,是奧特曼的弟弟,可牛逼了;MOTO是摩托羅拉,是摩托也要用騾來拉,可戳了。!保◣煾刚媸莻神!。。┮虼瞬荒芤恢甭裨筧ltera,他們做的事情一般都是有哥根據的。
下面貼上代碼,呵呵,給自己留個底:
一般情況下,不管你Enable bit_clearing怎么配置,給1 清零永遠不會錯。!
/*
* sys_main.c
*
* Created on: 2011-4-1
* Author: CrazyBingo
*/
#include <stdio.h>
#include "unistd.h"
#include "system.h"
#include "alt_types.h"
#include "sys/alt_irq.h"
//#include "io.h"
#include "altera_avalon_pio_regs.h"
//#include "../inc/my_sopc.h"
//#include "../inc/key_scan.h"
void key_interrupts(void * key_isr_context);
void key_interrupts_init(void);
// 定義全局變量以儲存邊沿捕獲值
volatile int edge_capture;
int main(void)
{
key_interrupts_init();
while(1)
{
IOWR_ALTERA_AVALON_PIO_DATA(LED_DATA_BASE, edge_capture);
}
return 0;
}
//* 按鍵中斷初始化 */
void key_interrupts_init(void)
{
/**//* Recast the edge_capture pointer to match the alt_irq_register() function
* prototype. */
void* edge_capture_ptr = (void*) &edge_capture;
/**//* Enable all 2 button interrupts. */
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(KEY_DATA_BASE, 0x03);
/**//* Reset the edge capture register.Enable bit_clearing turn0 off, write any vaule will take effect */
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(KEY_DATA_BASE, 0x03); //active High always take effect
/**//* Register the interrupt handler. */
alt_ic_isr_register
(
KEY_DATA_IRQ_INTERRUPT_CONTROLLER_ID, // 中斷控制器標號,從system.h復制
KEY_DATA_IRQ, // 硬件中斷號,從system.h復制
key_interrupts, // 中斷服務子函數
edge_capture_ptr, // 指向與設備驅動實例相關的數據結構體
NULL // flags,保留未用
);
}
//按鍵中斷服務程序(Interrupt service routime),每次下降沿進入中斷執行一次
void key_interrupts(void * key_isr_context)
{
/**//* Cast context to edge_capture's type. It is important that this be
* declared volatile to avoid unwanted compiler optimization.
*/
volatile int* edge_capture_ptr = (volatile int*) key_isr_context;
/**//* Store the value in the Button's edge capture register in *context. */
*edge_capture_ptr = IORD_ALTERA_AVALON_PIO_EDGE_CAP(KEY_DATA_BASE);
/**//* Reset the edge capture register. */
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(KEY_DATA_BASE,0x03);
}
終于可以進行我下一步了。。。柳暗花明----有時候,解決為什么比解決怎么做更加的痛苦,但此時解決了師父和牙縫的的失誤,同時,我終于可以放松一下了,這陣子因為這個中斷,因為Cyclone III PCB,快讓我over了,不過終于解決了問題,累著并且開心著。
歡迎光臨 (http://m.zg4o1577.cn/bbs/) |
Powered by Discuz! X3.1 |
主站蜘蛛池模板:
欧美日韩亚洲一区
|
婷婷不卡|
日韩中文一区
|
国产精品美女久久久久久免费
|
成人中文字幕在线观看
|
黄a在线观看
|
av网站推荐|
男人阁久久
|
久久久久久久久淑女av国产精品
|
91久久北条麻妃一区二区三区
|
精品一二区|
国产精品久久久久久久午夜片
|
久久久激情|
亚洲第一在线视频
|
99re视频
|
免费在线播放黄色
|
97国产成人
|
亚洲国产看片
|
日韩三级免费网站
|
久久精品一区二区视频
|
欧美一级二级在线观看
|
久久久亚洲成人
|
在线观看亚洲专区
|
久久久日韩精品一区二区三区
|
中文字幕av一区
|
日韩在线免费电影
|
九九久视频
|
亚洲人成一区二区三区性色
|
黄色欧美
|
亚洲精品一区中文字幕乱码
|
紧缚调教一区二区三区视频
|
亚洲欧美一区二区三区国产精品
|
99视频入口|
久久新视频
|
精品欧美一区免费观看α√
|
亚洲视频在线免费观看
|
久久国产欧美一区二区三区精品
|
激情91|
91久久婷婷
|
欧美一区二区久久
|
日本成人中文字幕
|