GSM_w_elektronice_cz5.pdf
(
412 KB
)
Pobierz
Elektronika Praktyczna
kurs
w elektronice (5)
Open AT – komendy AT, pamięć
Flash
Dodatkowe materiały
na CD i FTP
W poprzednim odcinku
zajmowaliśmy się między
innymi tworzeniem własnych
komend AT. W tym pokażemy,
jak stosować do swoich celów
komendy AT oferowane przez
system operacyjny. Pokażemy
również, jak wykorzystać
pamięć nieulotną do trwałego
przechowywania danych.
Listing 1. sprawdzanie stanu zalogowania się modemu do sieci GsM
#include
“adl_global.h”
const
u16 wm_apmCustomStackSize = 1024*3;
#deine
GPRS_PINCODE “9172”
s8 sms_handle;
static
void
poll_creg
( u8 Id );
void
Wyslij_SMS
(){
adl_smsSend
( sms_handle, “+48xxxxxxxxx”, “TEST SMS”, ADL_SMS_MODE_
TEXT );
}
static
bool
poll_creg_callback
(adl_atResponse_t *Rsp) {
ascii regStateString[3];
s32 regStateInt;
TRACE (( 1, “poll_creg_callback” ));
wm_strGetParameterString
(regStateString, Rsp->StrData, 2);
regStateInt = wm_atoi(regStateString);
if
( 1 == regStateInt || 5 ==regStateInt) {
TRACE (( 1, „poll_creg_callback - zalogowany w sieci” ));
Wyslij_SMS();
}
else
{
/* Nie gotowy - sprawdz ponownie za 1s */
adl_tmrSubscribe
( FALSE, 10, ADL_TMR_TYPE_100MS,
poll_creg);
}
return
FALSE;
}
static
void
poll_creg
( u8 Id ) {
adl_atCmdCreate
( “AT+CREG?”, FALSE, poll_creg_callback, ADL_STR_CREG, NULL);
}
static
void
SIM_Handler
( u8 event) {
TRACE (( 1, “SIM_Handler” ));
if
( event == ADL_SIM_EVENT_FULL_INIT) {
Na jakość działania i niezawodność pro-
jektu M2M duży wpływ ma to, czy na eta-
pie projektowania będziemy w stanie prze-
widzieć wszystkie okoliczności, które mogą
wystąpić podczas pracy urządzenia. W po-
przednim odcinku, gdy opisywaliśmy serwis
SIM oraz SMS, dla uproszczenia przyjąłem,
że
ADL_SIM_EVENT_FULL_INIT
oznacza, że
modem jest zalogowany i można już wysyłać
SMS. Tak jednak będzie tylko wtedy, gdy mo-
dem znajduje się w miejscu, w którym jest
dobry sygnał GSM, a sieć działa prawidłowo
i nie jest przeciążona. Aby jednak bez wzglę-
du na okoliczności być pewnym, że modem
jest zalogowany, posłużymy się komendą
AT+CREG. Komenda ta, wydana ze znakiem
zapytania, zwraca status zalogowania się
aparatu do sieci. W aplikacji pokazanej na
li-
stingu 1
komenda ta jest wydawana cyklicz-
nie, aż do otrzymania odpowiedzi „1” (zalo-
gowany) lub „5” (zalogowany w roamingu).
Zaprezentowana aplikacja w większości
przedstawia to, czego już nauczyliśmy się z po-
przednich odcinków kursu z tym, że tu SMS
zostanie wysłany tylko wtedy, kiedy modem
faktycznie zaloguje się do sieci. Dla przykładu,
jeśli odłączymy antenę GSM, to mimo iż zaj-
dzie zdarzenie
ADL_SIM_EVENT_FULL_INIT
,
to jednak SMS nie zostanie wysłany. Wszyst-
ko to dzięki kontroli odpowiedzi na komendę
AT+CREG?
. Sprawdźmy jak wygląda odpo-
wiedź modemu, jeśli komendę
AT+CREG?
wydamy do modemu z terminala (odpowiedź
modemu napisano pogrubioną czcionką):
AT+CREG?
+CREG: 0,1
TRACE (( 1, “SIM Full Init” ));
poll_creg(0);
}
}
bool
SMS_handler
( ascii * SmsTel, ascii * SmsTimeOrLength, ascii * SmsText ){
return
TRUE;
}
void
SMS_Control
( u8 Event, u16 Nb ){
}
void
adl_main
( adl_InitType_e InitType )
{
TRACE (( 1, “Embedded Application : Main” ));
adl_simSubscribe
( SIM_Handler, GPRS_PINCODE);
sms_handle =
adl_smsSubscribe
(SMS_handler, SMS_Control, ADL_SMS_MODE_
TEXT );
TRACE((1,”SMS handle = %d”, sms_handle));
}
OK
pomocą funkcji
adl_atCmdCreate()
podajemy
funkcję, która będzie otrzymywała odpowiedź
na wskazaną komendę AT, a także iltr odpo-
wiedzi, które chcemy przechwytywać. W na-
Mamy dwie odpowiedzi: jedna to
„
+CREG: 0,1
”, natomiast druga to „
OK
”. W na-
szej aplikacji wydając komendę
AT+CREG?
za
68
ELEKTRONIKA PRAKTYCZNA 7/2010
Technologia GSM
Open AT – komendy AT, pamięć Flash
Listing 2. Przykład konigurowania portu szeregowego
#include
“adl_global.h”
const
u16 wm_apmCustomStackSize = 1024*3;
void
Wylacz
( u8 ID,
void
* Context){
TRACE((1,”Wylacz UART2”));
adl_atCmdCreate
( “AT+WMFM=0,0,2” ,FALSE , NULL, NULL);
}
bool
Conf_Handler
(adl_atResponse_t * strc){
TRACE (( 1, “Conf_Handler: response = %d”,strc->RspID ));
if
(strc->RspID==ADL_STR_OK) {
adl_atSendResponse
( ADL_AT_PORT_TYPE(ADL_AT_UART2,ADL_AT_RSP),”Hello
World UART2\r\n” );
adl_tmrSubscribe
(FALSE,10,ADL_TMR_TYPE_100MS,Wylacz);
}
return
TRUE;
}
bool
Open_Handler
(adl_atResponse_t * strc){
TRACE (( 1, “Open_Handler: response = %d”,strc->RspID ));
if
(strc->RspID==ADL_STR_OK || strc->RspID==ADL_STR_CME_ERROR) {
adl_atCmdCreate
( “AT+IPR=9600;+IFC=0,0” ,ADL_AT_PORT_TYPE(ADL_AT_
UART2, FALSE), Conf_Handler , “*” , NULL);
}
return
TRUE;
}
void
adl_main
( adl_InitType_e InitType )
{
TRACE (( 1, “Embedded Application : Main” ));
adl_atCmdCreate
( “AT+WMFM=0,1,2” ,FALSE , Open_Handler , “*” , NULL);
}
szym przypadku jest to
ADL_STR_CREG
, czyli
jak w deinicji – string w postaci: „
+CREG:
”.
Jako iltr możemy podać kilka ciągów znako-
wych oddzielonych przecinkiem i zakończo-
nych wartością NULL lub jeśli chcemy prze-
chwytywać wszystkie możliwe odpowiedzi,
to jako argument podajemy „*”. Za pomocą
funkcji
wm_strGetParameterString()
pobiera-
my drugi parametr odpowiedzi i sprawdzamy
czy jest równy wartości „1” lub „5”. Jeśli tak, to
wykonywana jest funkcja
Wyslij_SMS
, w prze-
ciwnym razie uruchamiany jest jednorazowy
timer, który po sekundzie ponownie wywoła
funkcję pytającą o stan zalogowania. Funkcja
static void poll_creg(u8 Id)
może
być bez argu-
mentów, ale wykorzystywana jest również jako
funkcja – handler dla timera, a wtedy już musi
być w określonej postaci. Jeśli chcielibyśmy
zobaczyć przechwyconą odpowiedź w całości,
to najlepiej wewnątrz funkcji
poll_creg_call-
back()
dodać linijkę:
TRACE((1,Rsp->StrData));
W przedstawiony powyżej sposób moż-
na również odczytywać odbierany poziom
sygnału GSM. Należałoby w takim przypad-
ku skorzystać z komendy
AT+CSQ
.
Wydawanie komend AT wewnątrz apli-
kacji jest bardzo przydatna, możliwości nie
tylko do celów diagnostycznych, ale również
koniguracyjnych. Na
listingu 2
umieszczo-
no przykład konigurujący port szeregowy.
Aplikacja włącza port UART2 komendą
AT+WMFM=0,1,2
i czeka na odpowiedź.
Wyjątkowo w tym przypadku, oprócz od-
powiedzi
OK
za poprawną przyjmowana
jest również odpowiedź
CME_ERROR
. Za-
stosowano takie uproszczenie, aby pomi-
nąć sprawdzanie czy UART2 jest włączony
przed wydaniem komendy. Próba ponowne-
go włączenia już włączonego portu generuje
właśnie odpowiedź ERROR. Jeśli wiemy, że
tak właśnie jest, to takie rozwiązanie jest do
zaakceptowania. Po wydaniu komendy włą-
czającej port, aplikacja ustawia następujące
parametry transmisji: prędkość 9600 bps
oraz wyłączona kontrola przepływu. Wyda-
nie komendy
AT+IPR=9600;+IFC=0,0
jest
równoznaczne z wydaniem dwóch komend
AT+IPR=9600
AT+IFC=0,0
W odpowiedzi na komendę sklejoną
otrzymamy
OK
tylko wtedy, jeśli obie komen-
dy zwrócą odpowiedzi
OK
.
Po ustawieniu żądanych parametrów,
przez UART2 zostaje wysłany komunikat,
a następnie port zostaje wyłączony. Należy
zwrócić uwagę na zastosowane makro
ADL_
AT_PORT_TYPE()
. W przypadku funkcji, któ-
ra włącza i wyłącza UART2, po komendzie
AT pojawia się wartość
FALSE
. Oznacza
ona, że odpowiedzi które pomijamy przy
przechwytywaniu również nie pojawią się
w oknie terminala. Komenda AT jest w tym
przypadku wydawana w sposób „anonimo-
wy”. W przypadku ustawiania parametrów
Listing 3. Przykład użycia pamięci lash obiektów do przechowywania jednorazowo
wprowadzonego kodu PIN
#include
“adl_global.h”
const
u16 wm_apmCustomStackSize = 1024;
/*****************************************************************/
/* Local variables */
/*****************************************************************/
static
const
ascii * hand_name = “kod pin w pamieci lash”;
/*****************************************************************/
/* Local functions */
/*****************************************************************/
void
SimHandler
( u8 Event )
{
TRACE (( 1, “Embedded : SimHandler, Event=%d”,Event ));
switch
(Event){
case
ADL_SIM_EVENT_FULL_INIT:
adl_atSendResponse
( ADL_AT_UNS, “karta SIM zainicjalizowana\n\r”
);
break
;
case
ADL_SIM_EVENT_PIN_OK:
adl_atSendResponse
( ADL_AT_UNS, “SIM PIN ok\n\r” );
break
;
}//end switch
}//end simHandler
void
Fun_pin
(adl_atCmdPreParser_t * param) {
ascii * pin;
TRACE((1,”W Fun_pin”));
if
(param->Type == ADL_CMD_TYPE_PARA){
pin = ADL_GET_PARAM ( param, 0 ); //pobierz parametr komendy PIN
TRACE (( 3,pin));
TRACE((3,”Strlen of pin = %d”,
strlen
(pin) ));
}
if
(pin!=NULL){
adl_lhWrite
( hand_name, 0, wm_strlen(pin)+1, (u8 *) pin ); //zapisz
pin do p.lash
adl_simSubscribe
(SimHandler, pin ); //wpisz PIN do karty
}
adl_atSendStdResponse
(ADL_AT_RSP,ADL_STR_OK);
}
void
Fun_del
(adl_atCmdPreParser_t * param){
if
(
adl_lhExist
( hand_name, 0 )>0){
adl_lhErase
( hand_name, 0 );
}
adl_atSendStdResponse
(ADL_AT_RSP,ADL_STR_OK);
}
void
adl_main
( adl_InitType_e InitType )
ELEKTRONIKA PRAKTYCZNA 7/2010
69
kurs
portu musimy jawnie wskazać, którego por-
tu te ustawienia mają dotyczyć. W tym celu
stosujemy właśnie makro
ADL_AT_PORT_
TYPE()
. Pierwszym argumentem jest port,
a drugim laga o znaczeniu analogicznym,
jak w przypadku wywołania „anonimowe-
go”. To samo makro zostało również wyko-
rzystane w przypadku funkcji wysyłającej
tekst
adl_atSendResponse()
.
Więcej szczegółów dotyczących komend
AT wykorzystanych w przykładach znajdzie-
my dokumentacji (
Help –> Help Contents –>
Open AT Firmware Documentation –> Firm-
ware version R7.43
)
W modułach Air Prime Q26 Pamięć
Flash podzielono na następujące obszary:
–
pamięć Flash obiektów,
–
pamięć Application and Data (A&D),
–
pamięć kodu aplikacji.
Pamięć Flash obiektów jest to pamięć
o rozmiarze 384 kB (wielkość ta może
być zwiększona kosztem pamięci A&D do
1728 kB za pomocą aplikacji DWLWin) po-
zwalająca na zapisanie ponad 5000 obiek-
tów dowolnego typu, np. tablice, struktury,
zmienne. Maksymalny rozmiar pojedyncze-
go obiektu to 30 kB. W obszarze tym, w spo-
sób niewidoczny dla programisty, pracuje
mechanizm zwany
Garbage Collector
. Po-
woduje on równomierne wykorzystanie ca-
łego obszaru pamięci w taki sposób, że gdy
zmieniamy wartość pewnego obiektu, to nie
jest on zapisywany w tym samym obszarze
pamięci. Tak dzieje się do momentu, aż ob-
szar będzie całkowicie wykorzystany. Wtedy
zadziała
Garbage Collector
usuwając zwol-
nione komórki i wykonując defragmentację
pamięci. Mechanizm ten przedłuża czas ży-
cia pamięci Flash.
Obszar A&D jest również przeznaczony
na dane użytkownika, ale oprócz tego może
być wykorzystany do przechowania plików
irmware’u lub aplikacji w przypadku, gdy
korzysta się ze zdalnej aktualizacji. Obszar
ten jest dzielony z obszarem kodu aplikacji,
a jego rozmiar wynosi od 0 do 4864 kB. Za-
pisywanie danych w tym obszarze ogranicza
jedynie dostępna wielkość pamięci. Obszar
kodu aplikacji to miejsce, które jest zajęte
przez obecnie działającą aplikację. Rozmiar
tego obszaru to od 256 do 5120 kB. Propor-
cje pamięci przydzielone dla dwóch ostat-
nich obszarów można zmieniać komendą
AT+WOPEN=6
, np.:
AT+WOPEN=6
+WOPEN: 6,2560,2560
Odpowiedź zawiera ilość pamięci od-
powiednio dla pamięci A&D i kodu apli-
kacji. Jeśli wydamy komendę:
AT+WO-
PEN=6,4864
, to otrzymamy odpowiedź:
+WOPEN: 6,4864,256.
Należy pamiętać, że
zmieniając proporcje pamięci powodujemy
formatowanie całego obszaru pamięci A&D
oraz kodu aplikacji. Więcej informacji moż-
na znaleźć w dokumentacji komend AT oraz
Listing 3. c.d.
{
ascii * pin;
TRACE (( 1, “Embedded Application : Main” ));
if
(
adl_lhExist
( hand_name, 0 )>0){ //czy PIN zostal zapisany w p.lash
pin = (ascii *)
adl_memGet
(8);
wm_memset(pin, 0 ,8);
adl_lhRead
( hand_name, 0,8,(ascii *) pin);
adl_simSubscribe
(SimHandler, pin ); //WPISZ pin DO KARTY
adl_memRelease (pin);
}
else
{
adl_lhSubscribe
(hand_name, 1);
}
adl_atCmdSubscribe
(“AT+PIN”, Fun_pin, ADL_CMD_TYPE_PARA | 0x0011);
adl_atCmdSubscribe
(“AT+DEL”, Fun_del, ADL_CMD_TYPE_ACT );
}
Listing 4. Przykład użycia pamięci
Application & Data
#include
“adl_global.h”
/*************************************************************/
/* Mandatory variables */
/*-----------------------------------------------------------*/
/* wm_apmCustomStackSize */
/*-----------------------------------------------------------*/
/*************************************************************/
const
u16 wm_apmCustomStackSize = 1024*3;
/*************************************************************/
/* Local variables */
/*************************************************************/
ascii response[200]={0};
s32 cell_handle=0;
s32 event_handle=0;
/*************************************************************/
/* Local functions */
/*************************************************************/
void
Status
(){
adl_adState_t State;
adl_adGetState
( &State );
wm_sprintf(response,”Free memory size %d\r\n Deleted memory size\
t%d\r\n”
“Total memory size\t%d\r\nNumber of deleted items\
t%d\r\n”
“Number of allocated items\t%d\r\n”,
State.freemem,State.deletedmem,State.totalmem,State.
numdeleted,
State.numobjects);
adl_atSendResponse
(ADL_AT_RSP, response);
adl_atSendStdResponse
(ADL_AT_RSP,ADL_STR_OK);
}
void
Fun_sub
(adl_atCmdPreParser_t * param) {
TRACE((1,”Inside Fun-sub”));
ascii cell_s[12];
s32 cell_size;
wm_strcpy(cell_s, ADL_GET_PARAM ( param, 0 ));
cell_size = wm_atoi(cell_s);
TRACE((1,”size = %d”,cell_size));
cell_handle =
adl_adSubscribe
( 1, cell_size );
TRACE((1,”cell_handle = %d”,cell_handle));
if
(cell_handle>=0){
Status();
}
else
{
switch
(cell_handle){
case
ADL_RET_ERR_ALREADY_SUBSCRIBED:
adl_atSendResponse
(ADL_AT_RSP,”\r\nCell already subscribed\
r\n”);
break
;
case
ADL_AD_RET_ERR_OVERFLOW:
adl_atSendResponse
(ADL_AT_RSP,”\r\nOverlow\r\n”);
break
;
case
ADL_RET_ERR_BAD_STATE:
adl_atSendResponse
(ADL_AT_RSP,”\r\nBad State\r\n”);
break
;
}
}
}
void
Fun_del
(adl_atCmdPreParser_t * param){
s32 resp =
adl_adDelete
( cell_handle );
TRACE((1,”Del response= %d”,resp));
adl_atSendStdResponse
(ADL_AT_RSP,ADL_STR_OK);
Status();
}
void
Fun_wri
(adl_atCmdPreParser_t * param){
TRACE (( 1, “Fun_wri: text length %d”,param->StrLength ));
ascii * tekst;
tekst = ADL_GET_PARAM ( param, 0 );
//tekst[param->StrLength]=0;
TRACE((1,tekst));
70
ELEKTRONIKA PRAKTYCZNA 7/2010
Open AT – komendy AT, pamięć Flash
Listing 4. c.d.
if
(
adl_adWrite
( cell_handle, wm_strlen(tekst), (
void
*) tekst )>=0){
adl_atSendStdResponse
(ADL_AT_RSP,ADL_STR_OK);
}
else
Całą pamięć obiektów można skasować za
pomocą komendy
AT+WOPEN=3
(najpierw
jednak AT musi być zatrzymana aplikacja
Open
). Obiekty nie są natomiast kasowane
poprzez wgranie nowej aplikacji.
Na
listingu 4
umieszczono przykład
użycia pamięci
Application&Data
. Aplikacja
tworzy kilka komend AT, dzięki czemu bę-
dzie można wygodnie obserwować procesy
związane z funkcjonowaniem pamięci
.
Na początku należy wydać komendę
AT+SUB=”rozmiar”
powodując zadeklaro-
wanie w pamięci komórki o zadeklarowa-
nym rozmiarze wyrażonym w bajtach. Na-
stępnie można dokonać zapisu za pomocą
komendy
AT+WRITE=”dane do zapisania”
.
Pamięć A&D różni się też tym od pamię-
ci obiektów, że zapis jest dokonywany se-
kwencyjnie, a więc kolejne użycie komendy
AT+WRITE
spowoduje dodanie danych po
tych, które były zapisane wcześniej. Zapi-
sane wcześniej dane możemy odczytać za
pomocą funkcji
AT+READ
. Funkcja ta podaje
również rozmiar odczytywanej celi oraz ilość
wolnej pamięci w tej konkretnej komórce.
Na końcu odczytywanego wektora danych
jest dodawane 0, aby mógł być on wyświe-
tlony za pomocą funkcji
adl_atSendRespon-
se()
. W postaci komend AT zostały również
zaimplementowane funkcje formatowania
oraz kompaktowania pamięci. Rezultaty
ich działania są wyświetlane w oknie TRA-
CE przez wcześniej zadeklarowaną funkcję
event_Handler()
.
Do trwałego przechowywania danych
można w niektórych przypadkach również
użyć obszaru pamięci RAM, który nie jest
zerowany po miękkim lub twardym resecie.
W celu zapoznania się z tym sposobem prze-
chowywania danych polecam stworzenie
i uruchomienie przykładu „
Persistent RAM
”,
dostępnego wśród aplikacji przykładowych,
dostarczanych wraz z IDE.
Więcej informacji na temat produktów
Sierra Wireless można znaleźć na stronach
producenta: www.sierrawireless.com lub
kontaktując się z irmą ACTE Sp. z o.o., która
jest oicjalnym dystrybutorem opisywanych
produktów oraz zapewnia pełne wsparcie
techniczne.
adl_atSendStdResponse
(ADL_AT_RSP,ADL_STR_ERROR);
}
void
Fun_rea
(adl_atCmdPreParser_t * param){
adl_adInfo_t Dane;
if
(
adl_adInfo
( cell_handle, &Dane )== OK){
wm_sprintf(response,”Rozmiar\t%d\r\nPozostalo\t%d\r\n”,Dane.
size,Dane.remaining);
adl_atSendResponse
(ADL_AT_RSP,response);
wm_memcpy(response,Dane.data,Dane.size-Dane.remaining);
response[Dane.size-Dane.remaining]=0;
adl_atSendResponse
(ADL_AT_RSP,response);
TRACE((1,Dane.data));
adl_atSendStdResponse
(ADL_AT_RSP,ADL_STR_OK);
}
else
adl_atSendStdResponse
(ADL_AT_RSP,ADL_STR_ERROR);
void
Fun_rec
(adl_atCmdPreParser_t * param){
s32 resp =
adl_adRecompact
( event_handle );
TRACE((1,”Format response= %d”,resp));
adl_atSendStdResponse
(ADL_AT_RSP,ADL_STR_OK);
}
void
Fun_for
(adl_atCmdPreParser_t * param){
s32 resp =
adl_adFormat
( event_handle );
TRACE((1,”Format response= %d”,resp));
adl_atSendStdResponse
(ADL_AT_RSP,ADL_STR_OK);
}
void
event_Handler
( adl_adEvent_e Event, u32 Progress ){
}
void
adl_main
( adl_InitType_e InitType )
{
TRACE (( 1, “Embedded Application : Main” ));
//Status();
adl_atCmdSubscribe
(“AT+SUB”, Fun_sub, ADL_CMD_TYPE_PARA | 0x0011);
adl_atCmdSubscribe
(“AT+DEL”, Fun_del, ADL_CMD_TYPE_ACT );
adl_atCmdSubscribe
(“AT+WRITE”, Fun_wri, ADL_CMD_TYPE_PARA | 0x0011);
adl_atCmdSubscribe
(“AT+READ”, Fun_rea, ADL_CMD_TYPE_ACT );
adl_atCmdSubscribe
(“AT+FORMAT”, Fun_for, ADL_CMD_TYPE_ACT );
adl_atCmdSubscribe
(“AT+RECOMPACT”, Fun_rec, ADL_CMD_TYPE_ACT );
event_handle =
adl_adEventSubscribe
(&event_Handler);
}
TRACE((1,”event_Handler: Event %d progress %d”,Event,Progress));
w dokumentacji ADL w rozdziale „Memory
resources”.
Na
listingu 3
umieszczono przykład uży-
cia pamięci lash obiektów do przechowy-
wania jednorazowo wprowadzonego kodu
PIN. Aplikacja wprowadza dwie komendy
AT
–
jedną do wprowadzenia PIN-u i drugą
do jego usunięcia z pamięci. Wprowadzając
PIN do karty za pomocą komendy AT+PI-
N=”xxxx” powodujemy jego jednoczesne
zapisanie w pamięci. Jeśli jest to pierwsze
uruchomienie lub obiekt został wcześniej
usunięty, to aplikacja subskrybuje się do pa-
mięci lash, informując system operacyjny,
że będzie wykorzystywała tylko jeden obiekt.
Jeśli PIN został już raz wpisany za pomocą
komendy AT+PIN, to po każdym resecie
lub zaniku zasilania aplikacja sprawdza czy
istnieje obiekt, w którym powinien być zapi-
sany PIN, a następnie pobiera go z pamięci
za pomocą funkcji
adl_lhRead()
i wpisu-
je do karty za pomocą wcześniej poznanej
funkcji
adl_simSubscribe()
. Proszę zwrócić
uwagę, że obiekty przy odczycie i zapisie
adresowane są od zera. Istotne jest również,
że nie musimy znać wielkości obiektu w mo-
mencie subskrypcji pamięci lash, dopiero
w momencie jego zapisu do pamięci. W apli-
kacji zostało również pokazane dynamiczne
przydzielanie i zwalnianie pamięci RAM.
Adrian Chrzanowski
Acte sp. z o.o.
R
E
K
L
A
M
A
elektronikaB2B.pl
ELEKTRONIKA PRAKTYCZNA 7/2010
71
Plik z chomika:
insane2t
Inne pliki z tego folderu:
GSM_dla_elektronice_cz1.pdf
(421 KB)
GSM_w_elektronice_cz2.pdf
(4320 KB)
GSM_w_elektronice_cz3.pdf
(917 KB)
GSM_w_elektronice_cz4.pdf
(696 KB)
GSM_w_elektronice_cz5.pdf
(412 KB)
Inne foldery tego chomika:
APARATURA pomiarowa
ARDUINO
Automatyka i PLC
CadSoft EAGLE
Czasopisma
Zgłoś jeśli
naruszono regulamin