Search This Blog

Friday, June 18, 2010

Common Interrupt Pitfalls

SDCC Compiler User Guide ထဲမှာ ပါတဲ့ စိတ်ဝင်စား စရာ အချက်တချို့ကို ပြန်ပြော ချင်ပါတယ်။ ကျွန်တော့် အတွေ့အကြုံ အရ အဲဒီ အချက်တွေဟာ အရမ်းအရေး ကြီးပြီး firmware programmer တွေအတွက် အမြဲခေါင်းထဲမှာ ရှိနေဖို့ လိုတယ် လို့ ထင်ပါတယ်။ တစ်ခါက ကျွန်တော့် ပရိုဂရမ် မှာ ဘာ အမှားမှ မရှိပဲ သူ့ကို သုံးတဲ့အခါ တလွဲတွေပဲ လုပ်နေပါတယ်။ Stack overflow ဖြစ်နိုင်တာ ကို ရုတ်တရက် သတိရ ပြီး Stack အရွယ်အစား ပြင်လိုက်တဲ့ အခါ ကောင်းသွားတာ မျိုး မကြာခဏ ကြုံဖူးပါတယ်။

Variable not declared volatile

တစ်ခြား function တွေက သုံးနေတဲ့ variable တွေကို interrupt service routine တစ်ခု ခုကနေ ပြောင်းလဲပေး နေတဲ့ အခါမျိုးမှာ အဲဒီ variable တွေကို volatile လို့ ကြေငြာပေးရပါမယ်။ အသေးစိတ်ကို http://en.wikipedia.org/wiki/Volatile_variable မှာ ကြည့်နိုင်ပါတယ်။

Non-atomic access

အကယ်၍ variable ကို သုံးတာ instruction တစ်ခုမက လိုပြီး သူ့ကို သုံးနေချိန်မှာ interrupt ဝင်လာနိုင်ရင် ဒေတာ အမှား ဖြစ်မသွားဖို့ interrupt ကို disabled လုပ်ထားဖို့ လိုပါတယ်။ အဲဒီလို Bug မျိုးဟာ ပြန်တွေ့အောင် reproduce လုပ်ဖို့ခက်ပြီး ဒုက္ခ တော်တော် ပေးနိုင်ပါတယ်။ ကျွန်တော်တော့ Real time and embedded systems ဆရာက အတန်းထဲမှာ mutual exclusion... mutual exclusion နဲ့ ခဏ ခဏ ပြောတာ ကို ကောင်း ကောင်း မှတ်မိ နေ ခဲ့ ပေမယ့် အဲဒီ ပြဿနာ မျိုး တစ်ခါ တက်ဖြစ်အောင် ပြန်တက်ဖူးပြီး သင်ခန်းစာ ကောင်းကောင်း ပြန်ရဘူး ပါတယ်။

Stack overflow

ခေါ်ထားတဲ့ address တွေရယ်၊ သုံးလက်စ register တန်ဖိုး တွေ ကို stack ပေါ်မှာ တင်သိမ်းထားပြီး၊ stack အရွယ်အစား မလုံလောက်ရင် နဂို နေရာဆီ ပြန်မရောက်ပဲ တစ်ခြား မထင်မှတ်တဲ့ နေရာ တွေဆီ ရောက်သွားပြီး ဒုက္ခ တွေ့နိုင် ပါတယ်။

Use of non-reentrant functions

ဖြစ်နိုင်ရင် interrupt ထဲမှာ တစ်ခြား function တွေကို မခေါ်ပဲ တတ်နိုင်သမျှ ရှောင်ကျဉ် ပါ။ အကယ်၍ interrupt က active ဖြစ်နိုင်တဲ့ အခြေအနေ မျိုးမှာ nonreentrant function တွေကို main program ကနေ မခေါ်သင့်ပါဘူး။ Good luck with your programming!

Friday, June 11, 2010

Circular Buffered UART Com Module for 8051 Microcontroller

Embedded system အများစု မှာ UART communication ကို သုံးကြပါတယ်။ ဒါကြောင့် ကျွန်တော် ရေးထားတဲ့ circular buffered UART comm module လေးကို ဒီမှာ ဖော်ပြချင်ပါတယ်။ သူ့ကို 8051 microcontroller အတွက် ရေးထားတာ ဖြစ်ပေမယ့် တစ်ခြား microcontroller တွေ အတွက်ဆိုရင် လဲ အလွယ်တစ်ကူ ပြောင်းသုံးလို့ ရပါတယ်။

Using Circular Buffered UART Com Module

သူ့ကို သုံးချင်တဲ့ module မှာ ထုံးစံ အတိုင်း header file ကြေငြာဖို့ လိုပါတယ်။ ကျွန်တော့် နမူနာ မှာတော့ header အားလုံးကို 'headers.h' ဖိုင်ထဲမှာ စုထားတဲ့ အတွက် အဲဒီဖိုင်ကို ထည့်လိုက်ရုံ ပါပဲ။
ပို့ဖို့၊ လက်ခံဖို့ အတွက် buffer အရွယ်အစားတွေကို ComConfig.h မှာ သတ်မှတ် နိုင်ပါတယ်။ အဲဒီမှာပဲ ဒေတာ လက်ခံရရှိတဲ့ အခါ ခေါ်ချင်တဲ့ function ကို သတ်မှတ်နိုင်ပါတယ်။
main function ထဲမှာ buffer ထဲမှာ ဒေတာ တွေ ရောက်နေ မနေ စစ်ဖို့ ComChkRx() function ကို poll လုပ် နိုင်ပါတယ်။
နမူနာ source code ကို

UART-Timer-8051 on GitHub

မှာရယူ နိုင်ပါတယ်။

Thursday, June 10, 2010

Soft-Timer Module for 8051 Microcontroller

Embedded system အားလုံးလိုလို မှာ timer တွေကို သုံးကြပါတယ်။ 8051 microcontroller မှာ hardware timer နှစ်ခု၊ သုံးခု ပဲ ပါတဲ့ အတွက် ပုံမှန် system တစ်ခု အတွက် လိုအပ်တဲ့ timer အားလုံးကို hardware timer တွေပဲ သုံးပြီး ရေးမယ် ဆိုရင် လုံလောက်မှာ မဟုတ်ပါဘူး။ ဒါကြောင့် သိပ်ပြီး တိကျဖို့ မလိုတဲ့ timer တွေကို ရေးတဲ့အခါ software ကိုပဲ သုံးပါတယ်။ ဒီမှာ ကျွန်တော် ရေးထားတဲ့ soft-timer module လေး တစ်ခု အကြောင်း ကို ပြောချင်ပါတယ်။ သူ့ကို 8051 microcontroller အတွက် ရေးထားတာ ဖြစ်ပေမယ့် တစ်ခြား microcontroller တွေ အတွက်ဆိုရင် လဲ အလွယ်တစ်ကူ ပြောင်းသုံးလို့ ရပါတယ်။
နမူနာ source code ကို

UART-Timer-8051 on GitHub

မှာရယူ နိုင်ပါတယ်။

Using soft-timer module

သူ့ကို သုံးချင်တဲ့ module မှာ ထုံးစံ အတိုင်း header file ကြေငြာဖို့ လိုပါတယ်။ ကျွန်တော့် နမူနာ မှာတော့ header အားလုံးကို 'headers.h' ဖိုင်ထဲမှာ စုထားတဲ့ အတွက် အဲဒီဖိုင်ကို ထည့်လိုက်ရုံ ပါပဲ။
Timer က သတ်မှတ်ချိန် ကုန် လို့ time out ဖြစ်ရင် လုပ်ချင်တဲ့ function ရယ်၊ timer ရဲ့ အချိန် သတ်မှတ်ဖို့၊ timer စတင်ဖို့ အတွက် function များကိုရေးပါ။ ကျွန်တော့် နမူနာ မှာတော့ SysSBYLEDTmrTO() နဲ့ SysSBYLEDInit() တို့ကို System.c module ထဲမှာ ရေးထားပါတယ်။
TmrConfig.h ဖိုင်ကို ဖွင့်ပြီး အဲဒီမှာ ရှိတဲ့ အဆင့် သုံးဆင့် ကို လုပ်ဖို့ လိုပါတယ်။ သင့် compiler က function pointers တွေကို သုံးလို့ မရရင် switch structure နဲ့ ပြောင်းသုံး နိုင်ပါတယ်။
main function ထဲမှာ initialize လုပ်ဖို့ TmrInit() နဲ့ ပုံမှန် poll လုပ်နေဖို့ TmrTask() တွေကို ခေါ်ဖို့ လို့ပါတယ်။ သူတို့ကို Tmr.c ထဲမှာ ရေးထားပါတယ်။