C ARM программирование - PullRequest
0 голосов
/ 08 мая 2020

У меня было два вопроса относительно записи в регистры для программирования ARM с использованием языка C.

1-й: я пытаюсь записать в регистр управления прерыванием и сбросом приложения или AIRCR. Это 32-битный регистр. Мне нужно два значения записи 0x5FA в битах с 16 по 31 (необходимость в регистре). Мне также нужно изменить некоторые другие биты, но по отдельности. Я имел в виду, только побитовое (0 или 1). Я знаю, как это сделать, когда этого совсем немного. используя *iser0 |= 0UL << 2; например. Но мой вопрос в том, как я могу писать в часть регистра, а именно в AIRCR [31:16], имея возможность манипулировать другими битами.

2-й: Эта проблема не является моей основной проблемой, но когда я компилирую свою программу C, она возвращает не 0. Это ненормально? В чем была моя ошибка?

#include <stdint.h>

typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;

int main()
{
    //Multi drive register
    uint32_t* muer=(uint32_t*) 0x400E0E50UL;
    *muer |= 1UL << 8;

    uint32_t* mudr=(uint32_t*) 0x400E0E54UL;
    *mudr |= 0UL << 8;

    //Pio controller register
    uint32_t* per=(uint32_t*) 0x400E0E00UL;
    *per |= 1UL << 8;

    uint32_t* pdr=(uint32_t*) 0x400E0E04UL;
    *pdr |= 0UL << 8;

    //output register
    uint32_t* oer=(uint32_t*) 0x400E0E10UL;
    *oer |= 0UL << 8;

    uint32_t* odr=(uint32_t*) 0x400E0E14UL;
    *odr |= 1UL << 8;

    //edge select
    uint32_t* esr=(uint32_t*) 0x400E0EC0;
    *esr |= 1UL << 8;

    //level select
    uint32_t* lsr=(uint32_t*) 0x400E0EC4;
    *lsr |= 0UL << 8;

    //Rising edge
    uint32_t* rehlsr=(uint32_t*) 0x400E0ED4;
    *rehlsr |= 1UL << 8;

    //Falling edge edge
    uint32_t* fellsr=(uint32_t*) 0x400E0ED8;
    *fellsr |= 0UL << 8;

    //Interrupt set-enable register
    uint32_t* iser0=(uint32_t*) 0xE000E100;
    *iser0 |= 1UL << 11;

    //Interrupt clear-enable register
    uint32_t* icer0=(uint32_t*) 0xE000E180;
    *icer0 |= 0UL << 11;

    //AIRCR
    uint32_t* aircr=(uint32_t*) 0xFA050000;

    //VECTKEY
    *aircr |= 0x5FA << 16;

    //ENDIANESS
    *iser0 |= 0UL << 15;

    //PRIGRIOUP
    *iser0 |= 5UL << 8;

    //SYSRESETREQ
    *iser0 |= 0UL << 2;

    //VECTCLRACTIVE
    *iser0 |= 0UL << 1;

    //SYSRESETREQ
    *iser0 |= 0UL;
}

Это мой код.

Обновление: Я понял, что не могу сделать | = 0UL, вместо этого я должен использовать & = 1 << бит. Я пробовал это для своего другого кода. Но он по-прежнему не возвращает 0, и, что удивительно, для компиляции требуется 10 секунд. </p>

#include<stdint.h>


int main()
{

//Pull up register
volatile uint32_t* puer=(uint32_t*) 0x400E0E64UL;
*puer &= 1 << 8;


volatile uint32_t* pudr=(uint32_t*) 0x400E0E60UL;
*pudr |= 1UL << 8;


//Multi drive register
volatile uint32_t* muer=(uint32_t*) 0x400E0E50UL;
*muer &= 1 << 8;

volatile uint32_t* mudr=(uint32_t*) 0x400E0E54UL;
*mudr |= 1UL << 8;

//Pio controller register
volatile uint32_t* per=(uint32_t*) 0x400E0E00UL;
*per |= 1UL << 8;

volatile uint32_t* pdr=(uint32_t*) 0x400E0E04UL;
*pdr &= 1 << 8;


//ABSR register
volatile uint32_t* absr=(uint32_t*) 0x400E0E70UL;
*absr &= 1 << 8;

//output register
volatile uint32_t* oer=(uint32_t*) 0x400E0E10UL;
*oer |= 1UL << 8;

volatile uint32_t* odr=(uint32_t*) 0x400E0E14UL;
*odr &= 1 << 8;

}

Обновление Я не подключил свой микроконтроллер к своему P C. Одна из возможных проблем заключается в том, что на моем компьютере нет этих адресов?

1 Ответ

0 голосов
/ 08 мая 2020

Чтобы очистить один бит переменной, вы не используете *register |= 0 << bit, а вместо этого *register &= ~(1 << bit). Если вы хотите управлять более чем одним битом, по сути, вам нужно стереть соответствующую часть, а затем перезаписать ее желаемым шаблоном.

Это, например, удалит биты с 4 по 6, а затем перезапишет их с содержимым value:

*register &= 0x7 << 4
*register |= (value & 0x7) << 4;

Что касается вашего второго вопроса: никогда не пытайтесь запустить код, который пытается получить доступ к случайным ячейкам памяти, подобным этому, на P C. Это то, что вы делаете только для доступа к регистрам микроконтроллера. Ваш P C не имеет этих регистров, и даже если они есть, ваша операционная система все равно скрывает от вас фактическую физическую память.

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ:

Как как указал Лундин, использование битовых полей зависит от компилятора / архитектуры и, следовательно, непереносимо. Если вы хотите их использовать, вам нужно будет проверить документацию вашего компилятора, чтобы убедиться, что они работают должным образом. В случае сомнений предпочтите решение, указанное выше. Продолжайте читать на свой страх и риск; -)

С учетом этого, вы также можете сделать, чтобы избежать манипуляции с битами, примерно так:

union
{
    struct
    {
        uint32_t vectreset     :1;
        uint32_t vectclractive :1;
        uint32_t sysresetreq   :1;
        uint32_t               :5;
        uint32_t prigroup      :3;
        uint32_t               :4;
        uint32_t endianness    :1;
        uint32_t vectkey       :0;
    };
    uint32_t u32;
} *aircr = (void*)0xFA050000;

И затем в вашем коде получите доступ к битовому полю следующим образом: (*aircr).vectkey = 0x5FA;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...