Необходимо повторно прочитать регистр, используя mmap (). Значение чтения не обновляется. Мне нужно переназначить? - PullRequest
1 голос
/ 10 марта 2019

РЕДАКТИРОВАТЬ: вставлен неправильный код

Я нахожусь на Beaglebone Black под управлением Linux SDK TI, я верю 4.14.

Я думаю, что это довольно общий вопрос.вы, вероятно, можете перейти к следующему абзацу, но если вас волнует вот эта особенность: я пытаюсь отслеживать значение регистра TBCNT в EPWMSS2.Это счетчик.В соответствии с тем, как он настроен, при включении ШИМ счетчик увеличивается от 0 до некоторого числа, скажем, 32000, а затем снова начинается с 0. Я хочу сохранить текущее значение счетчика, которое я прочитал, а затем сравнить со следующим значением Iпрочитайте и проверьте, обнулился ли счетчик на 0. curr < last

определяет:

#define PWM2_OFFSET 0x48302000
#define PWM_SIZE 0x1000
#define TBCNT 0x8

I mmap() необходимые мне регистры, а затем каждые 100 мксек я печатаю значение регистра.Печатное значение не обновляется, оно всегда одинаково:

int main(){
    volatile unsigned int *pwm_mmap;
    int16_t *count;
    int fd;
    int i;    

    fd = open("/dev/mem", O_RDWR);
    if (fd < 0){
        fprintf(stderr, "open: %s\n", strerror(errno));
    }

    pwm_mmap = mmap(0, PWM_SIZE, PROT_READ, MAP_SHARED, fd, PWM2_OFFSET);
    if(pwm_mmap == MAP_FAILED) {
        fprintf(stderr, "mmap: %s\n", strerror(errno));
    }

    for(i=0;i<10;i++){

        *count = (void *)(pwm_mmap + TBCNT);
        printf("count = %d\n", *count);

        usleep(100);
    }

    if (munmap((void *)pwm_mmap, PWM_SIZE) < 0){
        fprintf(stderr, "munmap: %s\n", strerror(errno));
    }

}

, поэтому я попытался munmap() и повторно mmap() каждый раз, когда печатал значение.это сработало, я получил новое значение во второй раз, когда я сделал карту.Но я могу сделать это только дважды, и тогда я получаю mmap: cannot allocate memory:

int main(){
    volatile unsigned int *pwm_mmap;
    int16_t *count;
    int fd;
    int i;  

    fd = open("/dev/mem", O_RDWR);
    if (fd < 0){
        fprintf(stderr, "open: %s\n", strerror(errno));
    }

    for(i=0;i<10;i++){

        pwm_mmap = mmap(0, PWM_SIZE, PROT_READ, MAP_SHARED, fd, PWM2_OFFSET);
        if(pwm_mmap == MAP_FAILED) {
            fprintf(stderr, "mmap: %s\n", strerror(errno));
        }

        *count = (void *)(pwm_mmap + TBCNT);
        printf("count = %d\n", *count);

        if (munmap((void *)pwm_mmap, PWM_SIZE) < 0){
            fprintf(stderr, "munmap: %s\n", strerror(errno));
        }

        usleep(100);
    }
}

что я делаю не так?Я новичок в Mmap и регистры и действительно C в целом.Я уверен, что я злоупотребляю mmap() в некотором роде.Я ожидаю, что munmap() освобождает память, используемую *pwm_mmap, поэтому я не понимаю, почему у меня возникают проблемы с выделением памяти.Мне нужно malloc() pwm_map?

спасибо, ребята.

1 Ответ

1 голос
/ 10 марта 2019

Указатель, в котором хранится возвращаемое значение mmap(), не должен использовать тип volatile, поскольку вы не используете его напрямую для доступа к отображенным в памяти значениям.

Указатель, который необходимо использоватьтип volatile - это указатель, который разыменовывается для получения отображенного в память значения: count в вашем случае - он должен быть объявлен как:

volatile int16_t *count;

Цель volatile - заставитьдоступ к памяти каждый раз и не позволяет компилятору оптимизировать доступ и кэшировать значение (например, в регистре), когда он считает, что значение не изменилось.

Кроме того, как уже указывалось в одном из комментариев,присвоение count кажется неправильным.Что вам, вероятно, нужно:

count = (int16_t *)(pwm_mmap + TBCNT);

При исходном назначении вы записываете результат pwm_mmap + TBCNT в область памяти, на которую указывает count, которая является неинициализированным указателем в этой точке.В этом случае поведение не определено, но может вызвать ошибку сегментации.

Также обратите внимание на арифметику указателей.Поскольку pwm_mmap является указателем на unsigned int, адрес, который следует из pwm_mmap + TBCNT, является адресом, возвращаемым mmap() плюс TBCNT * sizeof(unsigned int), который, вероятно, равен 32 (при условии 32-битной платформы).Я не знаком с платформой, над которой вы работаете, но убедитесь, что вы правильно рассчитываете смещение регистра.

Сказав это, нет смысла переопределять каждый раз.Фактически, это было бы неэффективно, потому что (1) mmap / munmap являются системными вызовами, и это само по себе является большой накладной нагрузкой, и (2) в ядре выполняется много работы, чтобы выполнить фактическое отображение и отображение.

...