Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 5.00/9: Рейтинг темы: голосов - 9, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 26.11.2019
Сообщений: 31

Как работает указатель на typedef, определяющий структуру?

03.04.2024, 17:20. Показов 2248. Ответов 49
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!
Пытаюсь разобраться с тем, как работают библиотеки на МК. Увидел следующее:
C
1
((PM_TypeDef*)PM_BASE_ADDRESS) -> CLK_APB_M_SET = 1<<3;
Если пройтись по объявлениям написанного, то:
PM_TypeDef* - указатель на структуру, объявленную как тип (как я понимаю, просто для удобства обращения к её элементам)
Сама структура:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
typedef struct
    {   
       
      
        volatile uint32_t DIV_AHB;         
        volatile uint32_t DIV_APB_M;         
        volatile uint32_t DIV_APB_P;         
        volatile uint32_t CLK_AHB_SET;
        volatile uint32_t CLK_AHB_CLEAR;         
        volatile uint32_t CLK_APB_M_SET;
        volatile uint32_t CLK_APB_M_CLEAR;         
        volatile uint32_t CLK_APB_P_SET;
        volatile uint32_t CLK_APB_P_CLEAR;         
        volatile uint32_t AHB_CLK_MUX;
        volatile uint32_t WDT_CLK_MUX;    
        volatile uint32_t CPU_RTC_CLK_MUX;   
        volatile uint32_t TIMER_CFG;  
        volatile uint32_t FREQ_MASK;  
        volatile uint32_t FREQ_STATUS;  
        volatile uint32_t SLEEP_MODE;  
 
    } PM_TypeDef;
PM_BASE_ADDRESS через #define обозначен как 0x000050000

Как прочитать это ((PM_TypeDef*)PM_BASE_ADDRESS)?
Числу 0x000050000 явно задается тип, как тип указателя, т.е. 32 бита? (микроконтроллер 32-битный)
Имеет ли какой-то сакральный смысл то, что 0x000050000 - это 8.5 байт (9 чисел в hex)

Если это так, и числу 0x000050000 задали тип указателя, то далее (-> CLK_APB_M_SET = 1<<3) идет обращение к элементу структуры, хотя это не структура, а число (по моей явно неверной логике).

Иными словами, помогите, пожалуйста, расшифровать изначальную запись)
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
03.04.2024, 17:20
Ответы с готовыми решениями:

typedef (указатель на ф-ю) newtype, как сделать?
пытался затайпдефить указатель но чего-то никак( просто указатель работает, а как пытаюсь прикрутить typedef - ошибки. может в си нельзя...

Как объявить указатель на массив через typedef и как инициализировать такой тип
Как заставить заработать этот фрагмент кода? INT_L -- указатель на массив из 100 элементов типа char; Не получается в переменную C...

Без использования typedef все работает. При добавлении typedef — более 100 ошибок
Есть программа, с описанием структуры и функций, работающими с ней. Без использования typedef все работает. При добавлении typedef - более...

49
Нарушитель
10225 / 5655 / 1257
Регистрация: 12.03.2015
Сообщений: 26,183
03.04.2024, 17:38
Цитата Сообщение от adobson Посмотреть сообщение
Иными словами, помогите, пожалуйста, расшифровать изначальную запись)
Полю структуры присваивается значение 8. Чо непонятно?
Есть какая-то область памяти, начинающаяся с адреса PM_BASE_ADDRESS. Для удобства этот адрес приводится к типу указателя на структуру PM_TypeDef, чтоб получить доступ к полям по имени поля.
0
фрилансер
 Аватар для Алексей1153
6440 / 5634 / 1127
Регистрация: 11.10.2019
Сообщений: 14,980
03.04.2024, 18:34
adobson, typedef - это алиас. Всего лишь псевдоним, то есть

поэтому указатель "работает" точно так же, как указатель на структуру

Добавлено через 4 минуты
Цитата Сообщение от adobson Посмотреть сообщение
0x000050000
- это просто адрес. Видимо, в данном МК это константный адрес с особым значением

Добавлено через 1 минуту
Цитата Сообщение от adobson Посмотреть сообщение
как тип указателя, т.е. 32 бита? (микроконтроллер 32-битный)
тип указателя не обязательно 32 бита. Размер в байтах можно узнать так sizeof(*PM_TypeDef)
количество битов в байте == CHAR_BIT
1
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12919 / 6787 / 1817
Регистрация: 18.10.2014
Сообщений: 17,169
03.04.2024, 19:31
Лучший ответ Сообщение было отмечено adobson как решение

Решение

Цитата Сообщение от adobson Посмотреть сообщение
указатель на typedef
Нет такого понятия "указатель на typedef".

Цитата Сообщение от adobson Посмотреть сообщение
Как прочитать это ((PM_TypeDef*)PM_BASE_ADDRESS)?
(PM_TypeDef*) - это оператор явного приведения типа. Значение справа явно (читай: "насильно") приводится к тому типу, который указан в скобках.

В данном случае в скобках указан тип "указатель на структуру" (на ту самую структуру), а значение справа - это целочисленная константа 0x000050000.

Язык С сам по себе не определяет, что произойдет при приведении целочисленного значения к типу "указатель" (кроме, разве что, константы 0), но на практике вы в результате получите указатель на этот самый адрес. То есть выражение ((PM_TypeDef*)PM_BASE_ADDRESS) - это указатель типа PM_TypeDef*, соответствующий адресу 0x000050000.

А уж далее вы можете работать с этим указателем как угодно.
1
0 / 0 / 0
Регистрация: 26.11.2019
Сообщений: 31
04.04.2024, 15:44  [ТС]
Алексей1153, TheCalligrapher, Спасибо!
Я правильно понимаю, что создав такую структуру:
C
1
2
3
4
5
6
typedef struct 
    {
        volatile uint32_t ABC_1;
        volatile uint32_t ABC_2;
        volatile uint32_t ABC_3;
    } ABC_TypeDef;
и объявив
C
1
#define AAA 0x00
то сделав
C
1
2
#define BBB ((ABC_TypeDef*)AAA)
BBB->ABC_2 = 1<<3;
даст установку 3-го бита в ABC_2?
Т.е. запишет по адресу 0x00000004 байт 0x08?

Цитата Сообщение от Алексей1153 Посмотреть сообщение
тип указателя не обязательно 32 бита
Разве указатель не должен по размеру быть равен битности системы? Больше он, как я понимаю, быть не может, а меньше разве имеет смысл делать?
0
Нарушитель
10225 / 5655 / 1257
Регистрация: 12.03.2015
Сообщений: 26,183
04.04.2024, 15:49
Цитата Сообщение от adobson Посмотреть сообщение
Разве указатель не должен по размеру быть равен битности системы?
Не системы, а компилятора.

Добавлено через 1 минуту
Цитата Сообщение от adobson Посмотреть сообщение
#define BBB ((ABC_TypeDef*)AAA)
Если так сделать, то BBB будет равен NULL.
0
0 / 0 / 0
Регистрация: 26.11.2019
Сообщений: 31
04.04.2024, 16:12  [ТС]
Цитата Сообщение от Verevkin Посмотреть сообщение
Если так сделать, то BBB будет равен NULL
Но почему?
По сути же получается так
C
1
ABC_TypeDef *BBB = 0x00
т.е., как я это понимаю, указателю BBB типа ABC_TypeDef задается адрес 0x00
Как же тогда задать адрес начала структуры правильно?

Еще возник вопрос, немного касающийся темы обсуждения. Почему адресация в микроконтроллерах восьмибитная (если её вообще можно так назвать)? Это какая-то технологическая особенность или что-то исторически сложившееся?
0
Windows must die
828 / 834 / 102
Регистрация: 23.11.2021
Сообщений: 4,851
Записей в блоге: 15
04.04.2024, 16:14
Цитата Сообщение от adobson Посмотреть сообщение
Но почему?
Потому что по определению NULL = (void*)0;. И нигде адресное пространство не начинается с нуля!
Цитата Сообщение от adobson Посмотреть сообщение
Почему адресация в микроконтроллерах восьмибитная
Вообще-то, в 32-битных она 32-битная.
0
0 / 0 / 0
Регистрация: 26.11.2019
Сообщений: 31
04.04.2024, 16:18  [ТС]
Цитата Сообщение от Eddy_Em Посмотреть сообщение
И нигде адресное пространство не начинается с нуля
Это просто абстрактный пример) Я не собираюсь писать в МК что-то на нулевой адрес
Цитата Сообщение от Eddy_Em Посмотреть сообщение
в 32-битных она 32-битная
Неверно написал)
Почему она идет по байтам, а не по битам?
0
Нарушитель
10225 / 5655 / 1257
Регистрация: 12.03.2015
Сообщений: 26,183
04.04.2024, 16:19
Цитата Сообщение от adobson Посмотреть сообщение
Почему адресация в микроконтроллерах восьмибитная (если её вообще можно так назвать)?
Всё зависит от объёма и организации памяти. Микроконтроллеров разных существует - туева хуча.

Добавлено через 48 секунд
Цитата Сообщение от adobson Посмотреть сообщение
Почему она идет по байтам, а не по битам?
Патамушта никому нахрен не надо аппаратно адресовать отдельные биты.
0
0 / 0 / 0
Регистрация: 26.11.2019
Сообщений: 31
04.04.2024, 16:32  [ТС]
Цитата Сообщение от Eddy_Em Посмотреть сообщение
И нигде адресное пространство не начинается с нуля
Я тут вспомнил, что много где читай, что адресное пространство начинается с нуля.
Навскидку - https://masters.donntu.ru/2018... ticle5.pdf
Чему верить?)

Добавлено через 5 минут
Цитата Сообщение от Eddy_Em Посмотреть сообщение
Потому что по определению NULL = (void*)0;
Не понимаю... Где у меня по коду появляется пустой указатель?
0
Windows must die
828 / 834 / 102
Регистрация: 23.11.2021
Сообщений: 4,851
Записей в блоге: 15
04.04.2024, 16:35
Цитата Сообщение от Verevkin Посмотреть сообщение
никому нахрен не надо аппаратно адресовать отдельные биты
Есть и такое, bit-banding называется: выделяется область виртуальных адресов, где запись 1 или 0 в целый 32-битный регистр эквивалентна атомарному изменению одного бита в определенном регистре.
Цитата Сообщение от adobson Посмотреть сообщение
адресное пространство начинается с нуля
На тех редких старых архитектурах, где оно начиналось с нуля, NULL был определен как-то иначе (но всегда так, чтобы это был недопустимый адрес, например (void*)-1).

Добавлено через 1 минуту
Цитата Сообщение от adobson Посмотреть сообщение
Где у меня по коду появляется пустой указатель?
Вот же:
C
1
2
#define AAA 0x00
#define BBB ((ABC_TypeDef*)AAA)
Что эквивалентно объявлению NULL.
0
0 / 0 / 0
Регистрация: 26.11.2019
Сообщений: 31
04.04.2024, 16:45  [ТС]
Цитата Сообщение от Eddy_Em Посмотреть сообщение
Вот же:
Т.е. если я задам указатель на нулевой адрес это всё равно, что задать NULL? Даже с учётом того, что у него будет тип не (void*)?
Тогда невозможно что-то прописать в нулевой адрес? (это чисто теоретический вопрос, опять же, я туда писать ничего не планирую)

Добавлено через 3 минуты
Иными словами, если вместо #define AAA 0x00 написать, например, #define AAA 0x50, задастся структура с начальным адресом 0x50??
0
Windows must die
828 / 834 / 102
Регистрация: 23.11.2021
Сообщений: 4,851
Записей в блоге: 15
04.04.2024, 16:53
Цитата Сообщение от adobson Посмотреть сообщение
Даже с учётом того, что у него будет тип не (void*)?
Какая разница? При разыменовании получится разыменование нуля → сегфолт (а у микроконтроллера - зависание на хардфолте).
Цитата Сообщение от adobson Посмотреть сообщение
Тогда невозможно что-то прописать в нулевой адрес?
У МК нет ничего на нулевом адресе. Например, у STM8 адресное пространство начинается с 0x004000, причем, после option bytes есть "дыра", дальше память с 0x008000 продолжается (уже во flash). У STM32 еще больше таких "рваных кусков": RAM (может быть несколько секций), option bytes, flash и т.п. И тоже ничего с нуля не начинается - иначе пришлось бы как-то по-другому NULL определять.

Добавлено через 1 минуту
Цитата Сообщение от adobson Посмотреть сообщение
написать, например, #define AAA 0x50, задастся структура с начальным адресом 0x50?
Только это - тоже несуществующий адрес. Нужно брать реальный адрес из документации. А еще проще - взять готовые заголовочные файлы (если они, конечно, есть), где это все описано.
0
Нарушитель
10225 / 5655 / 1257
Регистрация: 12.03.2015
Сообщений: 26,183
04.04.2024, 17:13
Цитата Сообщение от Eddy_Em Посмотреть сообщение
Есть и такое, bit-banding называется: выделяется область виртуальных адресов, где запись 1 или 0 в целый 32-битный регистр эквивалентна атомарному изменению одного бита в определенном регистре.
Я написал слово "аппаратно" не просто так.
0
0 / 0 / 0
Регистрация: 26.11.2019
Сообщений: 31
04.04.2024, 17:17  [ТС]
Итак, если вместо 0x00 (или 0x50) написать
C
1
2
#define AAA *существующий адрес*
#define BBB ((ABC_TypeDef*)AAA)
то создастся структура с началом в этом самом *существующем адресе*, верно?
0
0 / 0 / 0
Регистрация: 26.11.2019
Сообщений: 31
04.04.2024, 17:30  [ТС]
Цитата Сообщение от Eddy_Em Посмотреть сообщение
И тоже ничего с нуля не начинается
Я что-то окончательно запутался. Вы говорите, что на нулевом адресе ничего нет. Как тогда воспринимать это?
Миниатюры
Как работает указатель на typedef, определяющий структуру?  
0
Windows must die
828 / 834 / 102
Регистрация: 23.11.2021
Сообщений: 4,851
Записей в блоге: 15
04.04.2024, 17:36
Да нет там ничего. Надо не размытый мануал на ядро смотреть, а на конкретный МК.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12919 / 6787 / 1817
Регистрация: 18.10.2014
Сообщений: 17,169
04.04.2024, 17:50
Цитата Сообщение от adobson Посмотреть сообщение
Но почему?
По сути же получается так
C
1
ABC_TypeDef *BBB = 0x00
т.е., как я это понимаю, указателю BBB типа ABC_TypeDef задается адрес 0x00
С точки зрения языка С - нет.

Константное значение 0 в указательных преобразованиях обрабатывается отдельно и особо. Она автоматически заменяется компилятором на внутреннее представление null-указателя на вашей платформе. То есть если на вашей платформе адрес 0 для чего-то занят, что null-указателя на вашей платформе, возможно, будет например 0xFFFFFFFF или что-то еще. То есть вполне может быть, что когда вы пишете ABC_TypeDef *BBB = 0x00 в указатель BBB фактически будет класться какой-нибудь 0xFFFFFFFF.

Цитата Сообщение от adobson Посмотреть сообщение
Как тогда воспринимать это?
Но там же ясно написано, что с адреса 0 обычно располагается код, а не данные. Там могут быть и данные, но вполне может быть, что ваша реализация С всегда помещает туда именно код.

А вы в своем вопросе ведете речь об указателях на данные. Во-первых, в языке С указатели на данные не обязаны уметь указывать на код - это определяется реализацией. Во-вторых, даже если на вашей платформе указателям на данные разрешают указывать на код, все равно может быть так, что адрес 0 вам "никогда не понадобится" и "использовать не разрешается". На такой платформе 0 будет вполне подходящим зарезервированным представлением для null-указателя.

В тех же атмеловских МК переход на адрес 0 вызывает софтверный перезапуск. То есть там адрес 0 имеет зарезервированный смысл. Это не адрес "общего назначения".
2
Нарушитель
10225 / 5655 / 1257
Регистрация: 12.03.2015
Сообщений: 26,183
04.04.2024, 17:57
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
То есть когда вы пишете ABC_TypeDef *BBB = 0x00 в указатель BBB фактически будет класться какой-нибудь 0xFFFFFFFF.
Это, кстати, можно проверить под дебаггером в эмуляторе за 6 секунд.

Добавлено через 6 минут
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Но там же ясно написано, что с адреса 0 обычно располагается код, а не данные. Там могут быть и данные, но вполне может быть, что ваша реализация С всегда помещает туда именно код.
Я контроллерами занимался давно, но помню, что по включению питания/сбросу CPU контроллера начинает выполнение с нуля. Именно поэтому адрес 0x00000000 никому никогда не понадобится - это начальный адрес головной инструкции. У меня это был jmp куда-то в начало главной петли.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
04.04.2024, 17:57
Помогаю со студенческими работами здесь

typedef и указатель на функцию
Здравствуйте! Помогите пожлауйста с пониманем одного момента... Так вот, есть оператор typedef.Он насколько я понял, обьявляет...

Как работает typedef?
Не совсем ясно как работает typedef. Я правильно понял, что Node идет как синоним для struct node, потом List идет как синоним для Node * ...

Записать указатель на функцию, не используя typedef
Имеется переменная - указатель на функцию fptr. Написать эту же переменную fptr, не используя typedef'ы /* Указатель на функцию void...

Указатель на шаблон класса через typedef
Здравствуйте. Возникла следующая проблема: захотел определить указатель на класс с template при помощи typedef, но вываливает ошибку: ...

Как работает оператор typedef
как работает оператор typedef если есть у кого сам код то пришлите,интересно:)


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru