Чтение из регистра процессора Allwinner H3 ARM - PullRequest
0 голосов
/ 15 января 2020
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>


static void foo(void){
    volatile  uint32_t *temp_addr;
    temp_addr = (uint32_t*)(0x01C20C00);
    *temp_addr =0;
}
int main(){
    tinit();

};

Компилируется, но в результате возвращает сообщение Segmentation fault. Я просто хочу сбросить все биты в регистре 0x01c200c00.

enter image description here

1 Ответ

1 голос
/ 15 января 2020

Ваша программа не работает, потому что 0x01C20C00 - это физический адрес, но ваша программа использует виртуальные адреса. Для экспериментов вы можете получить доступ к GPIO, таймерам или другим периферийным устройствам без написания драйвера ядра. Для этого вам нужно создать отображение памяти, например:

#define ALLWINNER_TIMER_BASE 0x01C20C00

struct allwinner_timer
{
  volatile uint32_t IRQ_EN_REG;
  // add other registers from the datasheet, or find a kernel driver source with these definitions
};

int fd = open("/dev/mem", O_RDWR);
struct allwinner_timer *t = (struct allwinner_timer *)mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, ALLWINNER_TIMER_BASE);
// TODO: check for errors
t->IRQ_EN_REG = 0;

Обратите внимание:

  • Может не работать, если ядро ​​ограничивает доступ к /dev/mem. Это можно узнать, посмотрев параметры ядра, например, CONFIG_STRICT_DEVMEM и с dmesg;
  • Очевидно, он должен работать под суперпользователем;
  • Ваш код может мешать работе других частей системы. Например, драйверы ядра обращаются к одному и тому же периферийному устройству, что приводит к непредсказуемым результатам.
...