Jump to content

    
Sign in to follow this  
Amper25

Как прочитать любую ячейку RAM.

Recommended Posts

Есть AVR у которого с помощью интерфейса внешней SRAM организован доступ так сказать к "периферии".

То есть, для обращения к этой "периферии", надо выполнять LDS/STS с адресным пространоством external SRAM.

 

В asm проблем нет, просто пишем нечто вроде STS ADDR,R16 ... и все.

 

А как заставить GCC обратится к такой-то конкретной ячейке памяти, при условии что эта ячейка находится во внешней SRAM?

А самой этой SRAM на самом деле нет. То есть нельзя линкеру сообщать что есть внешняя SRAM, чтобы он туда не запихал стек,

HEAP или еще что нибудь.

 

Делал давно подобное для IAR+ARM, но железно не могу вспомнить как именно.

Share this post


Link to post
Share on other sites
Есть AVR у которого с помощью интерфейса внешней SRAM организован доступ так сказать к "периферии".

То есть, для обращения к этой "периферии", надо выполнять LDS/STS с адресным пространоством external SRAM.

 

В asm проблем нет, просто пишем нечто вроде STS ADDR,R16 ... и все.

А кто мешает сделать функции rdp(...) и wrp(...), в которых бутет асемблерная вставка?

Share this post


Link to post
Share on other sites
Не, был метод попроще, что то вроде:

 

*(0xFFC0) = 125;

 

Но не могу впомнить и найти исходники.

 

Не, так в си нельзя вроде.

 

Если досуп побайтовый, то примерно так...

 

uchar* P;
...
P = (uchar*)0xFFC0;
*P = 125;

Share this post


Link to post
Share on other sites
// External SRAM page configuration: 
// 1100h - 7FFFh / 8000h - FFFFh
// Lower page wait state(s): None
// Upper page wait state(s): 1r/w
void XMEM_Initialize(void)
{
XMCRA = _BV(SRL2);
MCUCR |= (_BV(SRE) | _BV(SRW10));
}

void WriteByteAtAddress(WORD address, BYTE value)
{
BYTE *addr;
addr = (BYTE *) address;
*addr = value;
}

BYTE ReadByteAtAddress(WORD address)
{
BYTE *addr;
addr = (BYTE *) address;
return (*addr);
}

Share this post


Link to post
Share on other sites
void WriteByteAtAddress(WORD address, BYTE value)
{
BYTE *addr;
addr = (BYTE *) address;
*addr = value;
}

BYTE ReadByteAtAddress(WORD address)
{
BYTE *addr;
addr = (BYTE *) address;
return (*addr);
}

А для чего процедуры-то? Ведь так очень оверхед большой получается.

Уж лучше через #define или со static inline.

#define TOUCH_BYTE(ADDRESS)           (*(unsigned char*)(ADDRESS))
#define WRITE_BYTE(ADDRESS,DATA)      do {TOUCH_BYTE(ADDRESS) = (DATA);} while (0)
#define READ_BYTE(ADDRESS)            TOUCH_BYTE(ADDRESS)
// и далее в программе
unsigned char a;
a = TOUCH_BYTE(0x0100);    // читаем
TOUCH_BYTE(0x0100) = 45;  // пишем

Share this post


Link to post
Share on other sites
А для чего процедуры-то? Ведь так очень оверхед большой получается.

Уж лучше через #define или со static inline

Вы правы, моя ошибка, надо было и хедер показать. Там inline ;)

Share this post


Link to post
Share on other sites

Если говорить о стиле и точности, то стоит добавить const:

*(unsigned char * const)(0x8000) = 0x01;

 

Оптимизатор же все вышеизложенное сводит одинаково к:

LDI       R24,0x01       Load immediate
STS       0x8000,R24     Store direct to data space

 

Какой вариант использовать зависит исключительно от ситуации.

Edited by SysRq

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this