artkam 0 27 июня, 2016 Опубликовано 27 июня, 2016 · Жалоба Здравствуйте, уважаемые товарищи! В си-коде, для проверки состояния порта используется вставка на ассемблере, приведенная ниже. Но где-то что-то идет не так задумано, и в буфере, что передается в функцию по ссылке, ничего кроме нулей не обнаруживается. Возможно, я что-то недопонимаю и делаю не так, как надо. Хотелось бы услышать идеи, с помощью которых можно было бы починить код... void f(unsigned int* peg) { __ASM volatile ( ".equ PERIPH_BASE, 0x40000000 \n \t" ".equ AHB1PERIPH_BASE, 0x00020000 \n \t" ".equ GPIOD_BASE, 0x0C00 \n \t" ".equ GPIOB_BASE, 0x0400 \n \t" ".equ GPIO_IDR, 0x10 \n \t" ".equ GPIO_BSRRL, 0x18 \n \t" ".equ GPIO_BSRRH, 0x1A \n \t" ".equ GPIO_BSRR_BS_5, 0x20 \n \t" "LDR r0, =(GPIO_BSRR_BS_5) \n \t" "LDR r1, =(PERIPH_BASE + AHB1PERIPH_BASE + GPIOB_BASE + GPIO_BSRRH) \n\t" "LDR r2, =(PERIPH_BASE + AHB1PERIPH_BASE + GPIOB_BASE + GPIO_BSRRL) \n\t" "LDR r3, =(PERIPH_BASE + AHB1PERIPH_BASE + GPIOD_BASE + GPIO_IDR) \n\t" "LDR r4, [%[data_ptr], 0x00] \n \t" //0 "STRH r0, [r2, 0x00] \n \t" // set clock "LDR r5, [r3, 0x00] \n \t" // считываем GPIOD->IDR "STRH r0, [r1, 0x00] \n \t" // reset clock "STR r5, [r4, 0] \n \t" // записываем то, что было в GPIOD->IDR, в память со смещением //1 "STRH r0, [r2, 0x00] \n \t" "LDR r5, [r3, 0x00] \n \t" "STRH r0, [r1, 0x00] \n \t" "STR r5, [r4, 4] \n \t" //2 "STRH r0, [r2, 0x00] \n \t" "LDR r5, [r3, 0x00] \n \t" "STRH r0, [r1, 0x00] \n \t" "STR r5, [r4, 8] \n \t" /* Множество раз повторяется. */ //681 "STRH r0, [r2, 0x00] \n \t" "LDR r5, [r3, 0x00] \n \t" "STRH r0, [r1, 0x00] \n \t" "STR r5, [r4, #2724] \n \t" : : [data_ptr] "r" (peg) : ); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 27 июня, 2016 Опубликовано 27 июня, 2016 · Жалоба Не уверен насчет "сообразительности" инлайн ассемблера gcc: "LDR r0, =(GPIO_BSRR_BS_5) \n \t" здесь peg может быть затерт. И почему не оформить код в виде нормального ассемблерного модуля? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 30 27 июня, 2016 Опубликовано 27 июня, 2016 · Жалоба Здравствуйте, уважаемые товарищи! В си-коде, для проверки состояния порта используется вставка на ассемблере, приведенная ниже. Но где-то что-то идет не так задумано, и в буфере, что передается в функцию по ссылке, ничего кроме нулей не обнаруживается. Возможно, я что-то недопонимаю и делаю не так, как надо. Хотелось бы услышать идеи, с помощью которых можно было бы починить код... void f(unsigned int* peg) { __ASM volatile ( ".equ PERIPH_BASE, 0x40000000 \n \t" ".equ AHB1PERIPH_BASE, 0x00020000 \n \t" ".equ GPIOD_BASE, 0x0C00 \n \t" ".equ GPIOB_BASE, 0x0400 \n \t" ".equ GPIO_IDR, 0x10 \n \t" ".equ GPIO_BSRRL, 0x18 \n \t" ".equ GPIO_BSRRH, 0x1A \n \t" ".equ GPIO_BSRR_BS_5, 0x20 \n \t" "LDR r0, =(GPIO_BSRR_BS_5) \n \t" "LDR r1, =(PERIPH_BASE + AHB1PERIPH_BASE + GPIOB_BASE + GPIO_BSRRH) \n\t" "LDR r2, =(PERIPH_BASE + AHB1PERIPH_BASE + GPIOB_BASE + GPIO_BSRRL) \n\t" "LDR r3, =(PERIPH_BASE + AHB1PERIPH_BASE + GPIOD_BASE + GPIO_IDR) \n\t" "LDR r4, [%[data_ptr], 0x00] \n \t" //0 "STRH r0, [r2, 0x00] \n \t" // set clock "LDR r5, [r3, 0x00] \n \t" // считываем GPIOD->IDR "STRH r0, [r1, 0x00] \n \t" // reset clock "STR r5, [r4, 0] \n \t" // записываем то, что было в GPIOD->IDR, в память со смещением //1 "STRH r0, [r2, 0x00] \n \t" "LDR r5, [r3, 0x00] \n \t" "STRH r0, [r1, 0x00] \n \t" "STR r5, [r4, 4] \n \t" //2 "STRH r0, [r2, 0x00] \n \t" "LDR r5, [r3, 0x00] \n \t" "STRH r0, [r1, 0x00] \n \t" "STR r5, [r4, 8] \n \t" /* Множество раз повторяется. */ //681 "STRH r0, [r2, 0x00] \n \t" "LDR r5, [r3, 0x00] \n \t" "STRH r0, [r1, 0x00] \n \t" "STR r5, [r4, #2724] \n \t" : : [data_ptr] "r" (peg) : ); } Ну а под JTAGом пошагово почему не посмотреть что в регистры грузится? И не нужны будут ничьи идеи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 27 июня, 2016 Опубликовано 27 июня, 2016 · Жалоба Хотелось бы услышать идеи, с помощью которых можно было бы починить код... Вот такая идея: подключить внутрисхемный отладчик, пройтись по шагам в окне дизассемблера и разобраться, что именно идёт не так. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 30 27 июня, 2016 Опубликовано 27 июня, 2016 · Жалоба Не уверен насчет "сообразительности" инлайн ассемблера gcc: "LDR r0, =(GPIO_BSRR_BS_5) \n \t" здесь peg может быть затерт. И почему не оформить код в виде нормального ассемблерного модуля? R0 должен содержать 0x20 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 27 июня, 2016 Опубликовано 27 июня, 2016 · Жалоба Возможно, я что-то недопонимаю и делаю не так, как надо. Где сохранение разрушаемых R4,R5? Хотелось бы услышать идеи, с помощью которых можно было бы починить код... Вынести функцию в асм-файл. И читать документацию компилятора насчёт соглашений вызова. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 27 июня, 2016 Опубликовано 27 июня, 2016 · Жалоба : : [data_ptr] "r" (peg) : 1) Тут должны быть перечислены все используемые во вставке регистры и память ("=m", если правильно помню) 2) лучше дать возможность компилятору самому выделить наиболее подходящие регистры, т.е. задать там [имя] "+r" и во вставке использовать %[имя] вместо имени конкретного регистра - это развяжет ему руки. 3) аналогично peg можно заставить компилятор передавать во вставку адреса GPIOB->BSRRH, GPIOB->BSRRL, GPIOD->IDR чтобы брать их из заголовочного файла, а не прибивать гвоздями внутри вставки. 4) можно сэкономить регистр, занеся в регистр адрес GPIOB, а для обращений к BSRRH, BSRRL использовать разные смещения в командах. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artkam 0 28 июня, 2016 Опубликовано 28 июня, 2016 · Жалоба И почему не оформить код в виде нормального ассемблерного модуля? Наверно, можно оформить и в виде отдельного модуля... Но я не понимаю пока, какие преимущества я из этого смогу извлечь? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 28 июня, 2016 Опубликовано 28 июня, 2016 · Жалоба Наверно, можно оформить и в виде отдельного модуля... Но я не понимаю пока, какие преимущества я из этого смогу извлечь? А я думаю многие тут не понимают: какие преимущества Вы извлекаете нагородив этот огород с инлайн-ассемблером вместо простой си-функции? При этом даже не понимаете как взаимодействует Ваш асм-код с телом си-функции в которую его впихнули. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artkam 0 28 июня, 2016 Опубликовано 28 июня, 2016 · Жалоба Поэтому и обратился на форум, чтоб направили в правильном направлении, разъяснили основные моменты... В итоге, сделал вот так, в какой-то степени работает... void ClockAsm(unsigned int *peg) { __ASM volatile ( //"LDR r3, 0x4002041A \n \t" //"LDR r1, 0x40020418 \n \t" //"LDR r2, 0x40020C10 \n \t" //"MOV r3, 0x00000020 \n \t" ".equ PERIPH_BASE, 0x40000000 \n \t" ".equ AHB1PERIPH_BASE, 0x00020000 \n \t" ".equ GPIOD_BASE, 0x0C00 \n \t" ".equ GPIOB_BASE, 0x0400 \n \t" ".equ GPIO_IDR, 0x10 \n \t" ".equ GPIO_BSRRL, 0x18 \n \t" ".equ GPIO_BSRRH, 0x1A \n \t" ".equ GPIO_BSRR_BS_5, 0x20 \n \t" "LDR r3, [%[data_ptr], 0x00] \n \t" "LDR v1, =(GPIO_BSRR_BS_5) \n \t" "LDR v2, =(PERIPH_BASE + AHB1PERIPH_BASE + GPIOB_BASE + GPIO_BSRRH) \n \t" "LDR v3, =(PERIPH_BASE + AHB1PERIPH_BASE + GPIOB_BASE + GPIO_BSRRL) \n\t" "LDR v6, =(PERIPH_BASE + AHB1PERIPH_BASE + GPIOD_BASE + GPIO_IDR) \n\t" //0 "STRH v1, [v3, 0x00] \n \t" "LDR v5, [v6, 0x00] \n \t" "STRH v1, [v2, 0x00] \n \t" "STR v5, [r3, 0] \n \t" //1 "STRH v1, [v3, 0x00] \n \t" "LDR v5, [v6, 0x00] \n \t" "STRH v1, [v2, 0x00] \n \t" "STR v5, [r3, 4] \n \t" ... //338 "STRH v1, [v3, 0x00] \n \t" "LDR v5, [v6, 0x00] \n \t" "STRH v1, [v2, 0x00] \n \t" "STR v5, [r3, #1352] \n \t" : : [data_ptr] "r" (&peg) : "r3", "v1", "v2", "v3", "v5", "v6", "memory" ); } Теперь, следующая проблема: мне необходима выборка длиной 600 семплов, а, при увеличении шагов до 339, например, компилятор ругается: "Error: offset out of range"... Подскажите, возможно есть еще какая-то очевидная ошибка? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 28 июня, 2016 Опубликовано 28 июня, 2016 · Жалоба Поэтому и обратился на форум, чтоб направили в правильном направлении, разъяснили основные моменты... Правильное направление: пишите на си. Асм уместен только там, где реально нужен (очень редко!). И то - очень не советую использовать инлайн-асм. Лучше отдельный асм-файл. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 30 28 июня, 2016 Опубликовано 28 июня, 2016 · Жалоба Пусть тренируется человек, вон уже дошёл до факта, что смещение в виде константы [Rx, #(+-)N] имеет весьма ограниченный диапазон. ARM® and Thumb®-2 Instruction Set: QRC0001_UAL.pdf Если не надоест много занятного и полезного узнает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться