Перейти к содержанию
    

Формирование int из массива char

В каком именно месте происходит зависание, сказать не могу, процессор - 1986ВЕ1Т, там с дебагом туго.

Заставили?

 

Наверное проблема в том что промежуточные значения сохраняются в память,вместо того чтобы висеть в регистрах. Хотя для этого ну уж очень сильно постараться нужно, например объявить несколько глобальных переменных в регистрах мк - и превратить чип в реальный тормоз.

Решение в лоб - переменная uint32_t - для промежуточных вычислений.

И кстати, int - число со знаком равное размеру регистра мк, в этом случае с переносимостью кода будут проблемы, а так-же с простейшим сложением чисел без знака. На С можно любую ересть написать без юзанья int - и этот код будет выполняться на любом процессоре с одинаковым результатом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В каком именно месте происходит зависание, сказать не могу, процессор - 1986ВЕ1Т, там с дебагом туго.
Ничего туго там нет.

Пишется обработчик hard_fault и всё...

Главное, перед тем как применять этот проц, прочитать еррату, тогда вообще никаких сюрпризов.

 

Ну, а на счёт __packed для указателя, то в GCC аналогичного инструментария нет -

изучали эту тему несколько лет назад вдоль и поперёк.

Из того что удалось накопать сейчас - это __builtin_assume_aligned(ptr, align), но пока нет времени вникать как это использовать...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну, а на счёт __packed для указателя, то в GCC аналогичного инструментария нет -

изучали эту тему несколько лет назад вдоль и поперёк.

А я не очень-то понимаю, зачем этот инструментарий вообще где-то есть. Всё то же самое легко делается стандартными средствами языка (тот же memcpy), к тому же этот __packed внутри именно так и работает. ИМХО, это поощрение говнокода и привязка к компилятору, что не есть гут.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А я не очень-то понимаю, зачем этот инструментарий вообще где-то есть. Всё то же самое легко делается стандартными средствами языка (тот же memcpy), к тому же этот __packed внутри именно так и работает. ИМХО, это поощрение говнокода и привязка к компилятору, что не есть гут.

В смысле - так и работает? И при чём тут говнокод? То, что этот метод не универсален между компиляторами - конечно плохо.

Чтение __packed uint для Cortex-M скомпилится в одну инструкцию LDR, для ARM7/9 - в набор LDRB/ORR.

А с memcpy() - в разы более громоздко + нужна доп. память. Что для embedded применений может быть критично.

Более универсальный метод - определение класса с перегруженными операторами приведения типа и присваивания. Иногда я поступаю так если нужна переносимость. Но __packed - проще.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А я не очень-то понимаю, зачем этот инструментарий вообще где-то есть.
Удобно, когда можно объявить указатель "на куда угодно" и работать через него без всяких танцев с бубном...

ИМХО никакого говнокода.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ИМХО, это поощрение говнокода и привязка к компилятору, что не есть гут.
А по мне так наоборот - если происходит действие "обращение по указателю" - то логично было бы использовать предусмотренные для этого в языке средства разыменования указателя, а не захламлять исходник вызовами memcpy(). То, что этот указатель учитывает какие-то аппаратные особенности (невыровненный доступ), логично было бы как-то указать один раз при объявлении указателя (тот же __packed), а не распылять по исходнику в виде memcpy() и надеяться, что программист не забудет именно этот указатель использовать через memcpy().

 

В gcc можно обернуть искомые данные в упакованную структуру и обращаться по указателю на эту структуру.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну, а на счёт __packed для указателя, то в GCC аналогичного инструментария нет -

изучали эту тему несколько лет назад вдоль и поперёк.

Из того что удалось накопать сейчас - это __builtin_assume_aligned(ptr, align), но пока нет времени вникать как это использовать...

 

typedef volatile uint32_t REG32;
#define pREG32 (REG32 *)
#define USB_TXDATA                                (*(pREG32 (0x4002001C)))

uint8_t *pData;

USB_TXDATA = *((uint32_t __attribute__((packed)) *)pData);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

USB_TXDATA = *((uint32_t __attribute__((packed)) *)pData);

Как мёртвому припарка, то есть никакого эффекта. Собственно, и не должно работать, так как мануал пишет, что эта штука работает только с объявлением структуры, объединения или перечисления.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как мёртвому припарка, то есть никакого эффекта. Собственно, и не должно работать, так как мануал пишет, что эта штука работает только с объявлением структуры, объединения или перечисления.

 

Я взял это из примера от NXP.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я взял это из примера от NXP.

Ну и отлично. Передавайте им привет и попросите впредь не говнокодить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Передавайте им привет и попросите впредь не говнокодить.
Если этот пример для ARM компилятора, то имеет место быть...

А для gcc это не проходит, поэтому плохой пример NXP подаёт.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В gcc можно обернуть искомые данные в упакованную структуру и обращаться по указателю на эту структуру.

А поскольку так можно делать на любом компиляторе, то так не только можно, но и следует делать всегда.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Даже в случае безумного С кода, на асме получается необходимый минимум. В даже если проц не может читать/писать не выровненное - этот кусок он обязан выполнить.

 

    ldr      r1, =адрес_char
    mov     r3, #0
    ldrb    r0, [r1], #4
    add     r3, r3, r0,
    ldrb    r0, [r1], #4
    add     r3, r3, r0, lsl #8
    ldrb    r0, [r1], #4
    add     r3, r3, r0, lsl #16
    ldrb    r0, [r1], #4
    add     r3, r3, r0, lsl #24
    ldr     r1, =адрес_uint32_t
    str     r3, [r1]

Изменено пользователем AVI-crak

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Даже в случае безумного С кода, на асме получается необходимый минимум.

И это тоже. Прогресс в компиляторостроении привёл к тому, что вот эти стенания "а как же эти лишние две инструкции?" - зачастую устаревшая выдумка. Но даже если не так, пара лишних тактов и байтов вредит крайне редко. Короче, "преждевременная оптимизация", если говорить без матюков, но иметь в виду именно их :smile3009:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И это тоже. Прогресс в компиляторостроении привёл к тому, что вот эти стенания "а как же эти лишние две инструкции?" - зачастую устаревшая выдумка. Но даже если не так, пара лишних тактов и байтов вредит крайне редко. Короче, "преждевременная оптимизация", если говорить без матюков, но иметь в виду именно их :smile3009:

К чему в очередной раз поминание древней глупости - "преждевременная оптимизация" ?

http://electronix.ru/forum/index.php?showt...t&p=1348755

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...