2017-08-31 10 views
2

私は2017年にこの位置にいるとは信じられませんでしたが、私は多くの試みにもかかわらず、割り込みを処理することを絶対に拒否するターゲットシステム(LPC2138)を持っています。いろいろな理由から、私はそれを扱う必要があるので、それを乗り越えるだけの問題です。このアプリケーションは、いくつかの非同期I/Oストリーム(SPI、UART)とタイマー信号を備えた「割り込み優先」です。私の好意の1つは、プロセッサーがリアルタイム要件に比べて非常に高速であることです。そのため、余分な余裕があります。割り込みなしで埋め込まれたプログラミング

私が取り組んでいるアプローチは、I/Oを処理する3つのFIFOを含む1つの大きなポーリングされたループですべてを行うことです。一見したところ、それは実行可能なようですが、誰も経験に基づいてコメントを持っていますか?

割り込みの問題は簡単ではありません。システムがスクランブルされた状態でクラッシュすると、Webからまっすぐ離れた100%プラットフォーム互換のhello worldスニペットが機能しなくなります。誰かが知っているどこかに明確かつ専門的な修正があった場合、ポインタを高く評価します。

+0

作業をしない最小限のプログラムを提供してください... –

+1

あなたのタイミングに合っていれば、ポーリングに何の問題もなく、書き込みとデバッグがはるかに簡単です。 –

+0

私は、腕や他のmcusに非常に多くの経験があります。私の推測は、あなたの例は比較的巨大であり、あなたの足を濡らすことは必要ありません。 –

答えて

4

あなたのアプリケーションと目的のプラットフォームがよくわからないと、私はあなたに決定的な答えを与えることはできません!

しかし、経験に基づいてコメントを求めました。ここをクリック:-)

  1. リアルタイム要件が記載されています。割り込みを使わないで作業することは、実際にはそれを助けることができます!ハードリアルタイム要件を持つプロジェクトを実行したとき、割り込みを使用しませんでした。入ってくるデータストリームを処理していて、単語を処理するのにちょうど20人もいなければ、次のものを見逃してしまい、途中で途切れた1語を処理しているとしましょう。バング!次のものを失う。だから私たちはたくさんの投票をしました。別のアプリケーションでは、非リアルタイムコードなどを犠牲にして、タイムクリティカルな作業を処理する割り込みを使用して、設計上の決定が異なる場合があります。私が当時働いていた店舗の哲学は、非常に反撃的だった。

  2. ポーリングはいくつかのリソースを "無駄にする"ことがあります(実際には無駄ではありません:-))。しかし、あなたのプロセッサは十分に速いと言います。速度要件を満たすことができれば、ポーリングを楽​​しんでください。割り込みよりも扱いが簡単です。あなたのプログラムは、いつ何が起こるかをより詳細に制御します。

  3. FIFOが良好です。彼らはあなたのリアルタイム要件を和らげます。

  4. 私はあなたのhwデザインを全く知らないのですが、ロジックチップとフレキシブルなエンジニア(OK、これは擬似体です:-))を使用すると、入力のいくつかhwとhwロジックを使用して簡単な要件の一部を処理し、プログラムを簡単に書くためのインターフェイスを提供します(たとえば、特定のニーズに合わせて最適化されたFIFOでもかまいません。一度に情報を取得するなど)

あなたはいくつかの利点があるまったく新しいアプローチを学びます。

3

私たちはもっと多くの情報が必要な場合がありますが、小さなスケルトンはあなたが少なくともこれらのいくつかのことをしていることを確認します。あなたは前にarm7をやったことがありますか?これは初めてのことですか、またはあなたはarm7/armの世界に精通していますが、割り込みを働かせるだけですか?

start。s

.globl _start 
_start: 

.globl _start 
_start: 
    ldr pc,reset_handler 
    ldr pc,undefined_handler 
    ldr pc,swi_handler 
    ldr pc,prefetch_handler 
    ldr pc,data_handler 
    ldr pc,unused_handler 
    ldr pc,irq_handler 
    ldr pc,fiq_handler 
reset_handler:  .word reset 
undefined_handler: .word hang 
swi_handler:  .word hang 
prefetch_handler: .word hang 
data_handler:  .word hang 
unused_handler:  .word hang 
irq_handler:  .word irq 
fiq_handler:  .word hang 

reset: 
    ;@ (PSR_IRQ_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) 
    mov r0,#0xD2 
    msr cpsr_c,r0 
    ldr sp,=0x40002000 

    ;@ (PSR_FIQ_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) 
    mov r0,#0xD1 
    msr cpsr_c,r0 
    ldr sp,=0x40003000 

    ;@ (PSR_SVC_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) 
    mov r0,#0xD3 
    msr cpsr_c,r0 
    ldr sp,=0x40004000 

    bl notmain 
hang: b hang 

.globl PUT32 
PUT32: 
    str r1,[r0] 
    bx lr 

.globl GET32 
GET32: 
    ldr r0,[r0] 
    bx lr 

.globl dummy 
dummy: 
    bx lr 

.globl enable_irq 
enable_irq: 
    mrs r0,cpsr 
    bic r0,r0,#0x80 
    msr cpsr_c,r0 
    bx lr 

irq: 
    push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} 
    bl c_irq_handler 
    pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} 
    subs pc,lr,#4 

はい、あまりにも多くのレジスタです...コンパイラが他のものをカバーする揮発性のものだけが必要です。

notmain:

void c_irq_handler (void) 
{ 
} 
void notmain (void) 
{ 
    unsigned int ra; 
    for(ra=0;ra<100;ra++) dummy(ra); 
} 

MEMORY 
{ 
    rom : ORIGIN = 0x00000000, LENGTH = 0x1000 
    ram : ORIGIN = 0x40000000, LENGTH = 0x1000 
} 
SECTIONS 
{ 
    .text : { *(.text*) } > rom 
    .bss : { *(.bss*) } > ram 
} 

は、私はいつもあなたのso.list

を調べる

ビルド

arm-none-eabi-as start.s -o start.o 
arm-none-eabi-gcc -O2 -c notmain.c -o notmain.o 
arm-none-eabi-ld -T flash.ld start.o notmain.o -o so.elf 
arm-none-eabi-objdump -D so.elf > so.list 
arm-none-eabi-objcopy so.elf -O binary so.bin 

.bssの必要didntの推測flash.ld

彼らはあなたがそこにフラッシュを持っているか、彼らは彼らのブートローダにダンプする必要がある場合は、有効なユーザーコードのための

基準かどうかを判断するための興味深い方法を持っている:予約済みのARMは、ベクター 場所(0000 0014)を割り込む含まれている必要があります残りの割り込みベクタのチェックサムの2の補数。これは私がまだ、手またはプログラムを持っているが、後に一緒に来て、プログラム的にそれを行うことを行うことができませんdidntはチェックサムを一緒ベクトルのすべての が0

されます。この

ldr pc,reset_handler 
ldr pc,undefined_handler 
ldr pc,swi_handler 
ldr pc,prefetch_handler 
ldr pc,data_handler 
.word 0xb8a06f58 @ldr pc,unused_handler 
ldr pc,irq_handler 
ldr pc,fiq_handler 

変更をし、それが正常に動作する必要があります。

これが初心者にとってまったく役に立たない場合は、この回答を削除しても問題ありません。クロックはタイマーのために有効があった場合だけ手動didntのチェックからこれをきっ

void PUT32 (unsigned int, unsigned int); 
unsigned int GET32 (unsigned int); 
void enable_irq (void); 

#define T0IR 0xE0004000 
#define T0TCR 0xE0004004 
#define T0PC 0xE0004010 
#define T0MCR 0xE0004014 
#define T0TC 0xE0004008 
#define T0MCR0 0xE0004018 

void c_irq_handler (void) 
{ 
    PUT32(T0IR,1); 
} 
void notmain (void) 
{ 
    PUT32(T0TCR,2); 
    PUT32(T0TCR,0); 
    PUT32(T0TC,0); 
    PUT32(T0MCR0,0x100000); 
    PUT32(T0MCR,0x1); //3); 
    PUT32(T0TCR,1); 
    while(1) 
    { 
     if(GET32(T0IR&1)) break; 
    } 
    PUT32(T0IR,1); 

    PUT32(T0TCR,2); 
    PUT32(T0TCR,0); 
    PUT32(T0TC,0); 
    PUT32(T0MCR0,0x100000); 
    PUT32(T0MCR,0x1); //3); 
    PUT32(T0IR,1); 
    enable_irq(); 
    PUT32(T0TCR,1); 
    while(1) continue; 

} 

notmain.c

など個人的に私は大きなカウンターでLEDを点滅、最初のGPIOを取得ループ

for(ra=0;ra<0x20000;ra++) dummy(ra); 

は、UARTにつながるクロック速度を、把握することができ、このからの時間に基づいて点滅させ、その後、ポーリングモードでタイマーを使う(ちょうどそれがフリーランニングを始める)、アップ、UARTを取得、データを印刷するための簡単なルーチンを有する

、上記のようなコードを取ると私はタイマーでの各種レジスタをポーリングして印刷し、最終的にはTHEN割り込みもの
void hexstring (unsigned int d) 
{ 
    //unsigned int ra; 
    unsigned int rb; 
    unsigned int rc; 

    rb=32; 
    while(1) 
    { 
     rb-=4; 
     rc=(d>>rb)&0xF; 
     if(rc>9) rc+=0x37; else rc+=0x30; 
     uart_send(rc); 
     if(rb==0) break; 
    } 
    uart_send(0x0D); 
    uart_send(0x0A); 
} 

進はさらに簡単ですが、男はそれが難しい8進数で考えることです...

その割り込みレジスタがポーリングモードで最初に(2番目、3番目、4番目に)プロセッサに割り込みを許可せずに起動するかどうかを確認します(しばらくしないでください)。

周りのレベルでは、いったん私はそれを見ることができますが、そのようには動作しませんが、これは想定しています。そして、この場合にはそこにVICがある、と私は、これは

VICRawIntr 0xFFFFF008 

を登録すると仮定し、タイマ割り込みがアサートされて焼成した場合にもアサートされなければなりません。ペリフェラルで割り込みがクリアされたときに消滅することを確認してください(ビット4が表示されていることを確認してください)。

VICIntSelectがirqであるゼロにリセットされます。これは、今のところ触れてはいけないことです。

私は何が起こっているかを確認するためにプリントアウトし、再びポーリングことを行う、その後VICIntEnable

にビット4を設定すると仮定します。

VICIRQStatusの割り込み表示(まだ完全にポーリングしてもまだプロセッサにirqが有効にならない)が表示され、ペリフェラルがクリアされたときに離れるか、ペリフェラル割り込みがクリアされた場合にクリアする方法がわかりますこれほどまでにはなりません。

今は、irqをプロセッサに有効にする時間です。私は、それがポップアウトするのを見るためにバイトを押し込んでいます。または何かに導かれたフリック。

理論的には、周縁部をクリアして安全にアプリケーションに戻るために戻ってきます。

どのプロセッサでもmcuまたはフルサイズのプロセッサであっても、同じ手順に従います。割り込みは悪夢であり、テストしないとコードを書くほどコードが失敗する可能性が高くなります。テストごとに1行のコードが必要になることがあります。 YMMV。

もう一度これが完全に役に立たない場合は、申し訳ありませんが削除されます。私は2148年の1/2148を持っていると思いますが、2138年ではないと思います。このARMV7TDMIが外に出ていて、はるかに痛い現在のarmv8に人気が出て以来、アームを使用していました。 pi-zeroなどは、このarm7のような古い学校のようにかなり楽しいです。...

私は、タイマーが実際の割り込みを取得するのが簡単だと思います。私はそれがより多くの仕事だと思うが、gpioピンかもしれないが、ピンの間にジャンパーを結ぶだろう、このチップが出力gpioを使って入力の状態を変えるために、クリーンな方法で、順番に各レイヤーにヒットした割り込みを監視し、各レイヤーで毎回割り込みを取り除くことができるかどうかを確認する全体のポーリングプロセスを実行します。その後、コアの端に叩き込み、最後にコアに挿入します。

+0

例外テーブルのldr、pcsは、しばしば過度にラベルにブランチを使用することがあります。実際にはテーブルを動かす必要はありませんので、ブランチもうまくいきます。しかし、0x14の値を再計算して、チェックサムを渡してコードが実行されるようにしなければなりません。 –

+1

これを再現するには、最後の手段であるIMOを絶対に必要とする場合にのみ、割り込みを使用してください。 –

関連する問題