Russian Qt Forum
Март 29, 2024, 14:26 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QBS для микроконтроллера.  (Прочитано 18160 раз)
alex312
Хакер
*****
Offline Offline

Сообщений: 606



Просмотр профиля
« : Январь 28, 2014, 22:15 »

Пытаюсь разобраться с QBS и применить для сборки проектов под микроконтроллеры.
Конкретно сейчас под STM32F407 .
Накидал тестовый проект. Удалось добиться компилируемости. Получаю *.elf .
Но никак не могу понять как сделать так, что б из .elf генерировались *.hex и .bin .
Эти файлы ( *.hex и .bin) генерирует утилита из состава тулчейна. На вход ей надо подать ранее собранный *.elf .
Собственно вопрос в том как написать правила для QBS, что бы вызывалась нужная утилита после успешной компиляции *.elf.

Мой тестовый проект - https://dl.dropboxusercontent.com/u/88492657/test_arm_qbs.zip
Записан
b-s-a
Гость
« Ответ #1 : Январь 28, 2014, 23:19 »

эта утилита называется objcopy:
Код
$ objcopy -O binary -j .text prog.elf prog.bin
$ objcopy -O ihex -j .text prog.elf prog.hex

Вот тут написано как делать свои правила: http://stackoverflow.com/questions/17173825/how-can-a-qbs-build-rule-use-a-product и https://qt-project.org/doc/qbs-1.1/rule-item.html

Держи в курсе своих исследований QBS. Я тоже интересуюсь переходом на него вместо обычного Makefile, но заниматься исследованиями лень.
« Последнее редактирование: Январь 28, 2014, 23:26 от b-s-a » Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #2 : Январь 29, 2014, 10:42 »

1) И да, я еще для этой темы сделал патч в QBS скриптах чтобы можно было указывать линкер файлы/скрипты (*.ld) через отдельный список:
https://codereview.qt-project.org/#change,73035

Вроде оно работает (с одним скриптом), но нужно юнит тесты какие нить сделать и проверить с несколькими *.ld скриптами.
Например, где один скрипт - будет задавать размер стека, а второй,к примеру, распихивать код по секциям.

Типа:
Код:
cpp.linkerScripts: [ "stack.ld", "sections.ld" ]


2) И да, для компиляции можно использовать QtCreator v3.0 и выше с его плагином BareMetal.

3) У меня тоже есть тестовый проектик (пустой), если надо - могу добавить.

UPD: Но больше я не занимался этим, отошел от этой темы. Улыбающийся
« Последнее редактирование: Январь 29, 2014, 10:46 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
alex312
Хакер
*****
Offline Offline

Сообщений: 606



Просмотр профиля
« Ответ #3 : Январь 29, 2014, 19:26 »

3) У меня тоже есть тестовый проектик (пустой), если надо - могу добавить.
Выкладывай. Вообще я смог найти 3 проекта, которые используют QBS (QtCreator, QBS, qutim). Так что больше проектов.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #4 : Январь 29, 2014, 20:32 »

Приаттачил в этот пост (вроде бы тот архив, не могу сейчас проверить).
Записан

ArchLinux x86_64 / Win10 64 bit
alex312
Хакер
*****
Offline Offline

Сообщений: 606



Просмотр профиля
« Ответ #5 : Февраль 03, 2014, 16:36 »

Наваял простецкий проект мигания светодиодом (для STM32F4Discovery).
Собственно проект компилируется (получаю *.elf).
Проблему генерации *.hex и *.bin пока решил вызовом внешнего батника. Средствами QBS это решить пока не удалось.

Проект а аттаче.
Записан
alex312
Хакер
*****
Offline Offline

Сообщений: 606



Просмотр профиля
« Ответ #6 : Март 26, 2015, 07:19 »

Наваял модуль Qbs для генерации *.hex, *.bin и листинга.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #7 : Март 26, 2015, 11:31 »

Кстати, вместо:

Код:
flags = flags.concat(["-T",path+"/"+ld_script])

можно просто использовать:

Код:
cpp.linkerScripts: [ "STM32F4XX.ld" ]
Записан

ArchLinux x86_64 / Win10 64 bit
alex312
Хакер
*****
Offline Offline

Сообщений: 606



Просмотр профиля
« Ответ #8 : Март 26, 2015, 12:50 »

kuzulus, спасибо. Забыл это подправить.
Записан
arhiv6
Гость
« Ответ #9 : Октябрь 03, 2015, 23:47 »

Добрый день. Хочу использовать Qbs для программирования МК. Написал конфиг:
Код
Javascript
import qbs
 
Product {
   name: "AIP_firmware"
   type: ["application"]//,"hex","bin"]
   Depends { name:"cpp" }
   cpp.executableSuffix: ".elf"
 
   files: [
       "src/*.c",
       "src/*.h"
   ]
 
   cpp.includePaths: [
       "src/"
   ]
 
   cpp.commonCompilerFlags: [
       "-mmcu=msp430f5529",
       "-fdata-sections","-ffunction-sections",        
       "-Wl,-gc-sections",                            
       "-Os",                                        
       "-nostartfiles","-nostdlib","-nodefaultlibs",  
       "-std=gnu99","-Wall",                        
       "-D VERSION="+version                          
   ];
 
   cpp.linkerFlags:[
       "-mmcu=msp430f5529",
       "-fdata-sections","-ffunction-sections",      
       "-Wl,-gc-sections",                            
       "-Os",                                        
       "-nostartfiles","-nostdlib","-nodefaultlibs",  
       "-std=gnu99","-Wall",                          
       "-D VERSION="+version                          
   ];
 
   Rule {
      inputs: ["c"]
       Artifact {
           fileTags: ['obj']
           filePath: '.obj/' + qbs.getHash(input.baseDir) + '/' + input.fileName + '.o'
       }
       prepare: {
           var args = [];
           args = args.concat(product.compilerOptions)
           args.push('-J');
           args.push('-c');
           args.push(input.filePath);
           args.push('-o');
           args.push(output.filePath);
           var cmd = new Command(product.compilerPath, args);
           cmd.description = 'compiling ' + input.fileName;
           return cmd;
       }
   }
 
   Rule {
       multiplex: true
       inputs: ['obj']
       Artifact {
           fileTags: ['elf']
           filePath: product.name + '.elf'
       }
       prepare: {
           var args = [];
           args = args.concat(product.compilerOptions)
           for (i in inputs["obj"])
                       args.push(inputs["obj"][i].filePath);
           args.push('-o');
           args.push(output.filePath);
           var cmd = new Command(product.compilerPath, args);
           cmd.description = 'linking ' + product.name + product.compilerOptions;
           return cmd;
       }
   }
 
   Rule {
       inputs: "elf"
       Artifact {
           fileTags: ["bin"]
          filePath: product.name + ".bin"
       }
       prepare: {
               var args = ["-O", "binary", input.filePath, output.filePath];
               var cmd = new Command(product.objcopyPath, args);
               cmd.description = "converting to bin";
               return cmd;
       }
   }
 
   Rule {
       inputs: "elf"
       Artifact {
           fileTags: ["hex"]
           filePath: product.name + ".hex"
       }
       prepare: {
           var args = ["-O", "ihex", input.filePath, output.filePath];
           var cmd = new Command(product.objcopyPath, args);
           cmd.description = "converting to hex";
           return cmd;
       }
   }
}
Похожий конфиг я уже использовал, правда на другом компьютере и для другого МК. А сейчас то ли чего-то не дописал, то ли чего то не донастроил, но при сборке Qbs на меня ругается:
Код:
The following properties are not set. Set them in your profile or product: cpp.architecture: you might want to re-run 'qbs-setup-toolchains'
Похоже что-то не так с настройками. Решил переписать конфиг, чтобы явно указать используемый компилятор:
Код
Javascript
import qbs
 
Product {
   name: "AIP_firmware"
   type: ["elf","hex","bin"]
 
   property string version: "0.0"
   property string compilerPath: "/usr/bin/msp430-gcc"
   property string objcopyPath: "/usr/bin/msp430-objcopy"
   property var compilerOptions:  [
       "-mmcu=msp430f5529",
       "-fdata-sections","-ffunction-sections",        
       "-Wl,-gc-sections",                            
       "-Os",                                        
       "-nostartfiles","-nostdlib","-nodefaultlibs",  
       "-std=gnu99","-Wall",                          
       "-D VERSION="+version                          
   ];
 
   Group {
       name: "sources"
       files: 'src/*.c'
       fileTags: ['c']
   }
 
   Group {
       name: "headers"
       files: 'src/*.h'
       fileTags: ['h']
   }
 
   Rule {
      inputs: ["c"]
       Artifact {
           fileTags: ['obj']
           filePath: '.obj/' + qbs.getHash(input.baseDir) + '/' + input.fileName + '.o'
       }
       prepare: {
           var args = [];
           args = args.concat(product.compilerOptions)
           args.push('-c');
           args.push(input.filePath);
           args.push('-o');
           args.push(output.filePath);
           var cmd = new Command(product.compilerPath, args);
           cmd.description = 'compiling ' + input.fileName;
           return cmd;
       }
   }
 
   Rule {
       multiplex: true
       inputs: ['obj']
       Artifact {
           fileTags: ['elf']
           filePath: product.name + '.elf'
       }
       prepare: {
           var args = [];
           args = args.concat(product.compilerOptions)
           for (i in inputs["obj"])
                       args.push(inputs["obj"][i].filePath);
           args.push('-o');
           args.push(output.filePath);
           var cmd = new Command(product.compilerPath, args);
           cmd.description = 'linking ' + product.name + product.compilerOptions;
           return cmd;
       }
   }
 
   Rule {
       inputs: "elf"
       Artifact {
           fileTags: ["bin"]
          filePath: product.name + ".bin"
       }
       prepare: {
               var args = ["-O", "binary", input.filePath, output.filePath];
               var cmd = new Command(product.objcopyPath, args);
               cmd.description = "converting to bin";
               return cmd;
       }
   }
 
   Rule {
       inputs: "elf"
       Artifact {
           fileTags: ["hex"]
           filePath: product.name + ".hex"
       }
       prepare: {
           var args = ["-O", "ihex", input.filePath, output.filePath];
           var cmd = new Command(product.objcopyPath, args);
           cmd.description = "converting to hex";
           return cmd;
       }
   }
}
Конфиг рабочий, на выходе получаю скомпилированную программу в трёх вариантах (elf, hex, bin). Что не устраивает в таком подходе: для прошивки МК требуется выполнить команду вида:
Код:
/usr/local/bin/mspdebug tilib "prog path_to_my_file.bin reset"
Ок, чтобы это делать прямо из QtCreator, в настройках запуска указываю конфигурацию: Особая программа, Программа: /usr/local/bin/mspdebug, Аргументы запускаемой программы: tilib "prog %{DebuggedExecutable:FilePath} reset". Проблема в том, что переменная %{DebuggedExecutable:FilePath} почему-то пустая...
В общем, подскажите, пожалуйста, как мне допилить первый конфиг или для второго конфига определить переменную %{DebuggedExecutable:FilePath}. Заранее спасибо за ответы!
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #10 : Октябрь 04, 2015, 15:54 »

Цитировать
А сейчас то ли чего-то не дописал, то ли чего то не донастроил, но при сборке Qbs на меня ругается

Тут речь идет о профиле QBS, а не о твоем файле проекта. Т.к. ты указал в первом своем варианте зависимость от CPP, то QBS пытается собрать проект используя готовые профили (те, которые Kit-ы из QTCreator).. И, собственно, обламывается... т.к. нет подходящего профиля и быть не может, т.к. MSP это не ARM, ЕМНИП.

Поэтому первый вариант сам собой отпадает и нужно использовать второй, где мы сами "замещаем" CPP модуль, используя свои правила для компиляции, линковки и прочее (т.е. нельзя делать Depends { name:"cpp" } в этом случае).

Цитировать
Ок, чтобы это делать прямо из QtCreator, в настройках запуска указываю конфигурацию:

Можно создать под-проект, назвать его типа "Deployer" и пр. И в его правилах указать запуск

/usr/local/bin/mspdebug tilib "prog path_to_my_file.bin reset"

Конечно в его зависимости добавить Depends { name: AIP_firmware }, а в правило что-то типа

        inputsFromDependencies: [ "bin" ]

и вытянуть отсюда путь к "prog path_to_my_file.bin"


А можно проще - просто добавить еще одно правило Rule в котором на вход подавать bin, и оно будет делать прошивку автоматом.

Хотя, как по мне, я бы ручками прошивал и консоли сам. Улыбающийся
Записан

ArchLinux x86_64 / Win10 64 bit
arhiv6
Гость
« Ответ #11 : Октябрь 04, 2015, 17:32 »

kuzulis, создать ещё одно правило можно, но оно же будет выполняться каждый раз при сборку проекта? Я бы хотел отделить сборку проекта и прошивку МК (по действию "Запустить" (Ctrl+R)). QBS позволяет такое сделать? Я думал реализовать такое средствами QtCreaor (запуск сторонней программы - программатора), но не знаю, как правильно передать ему путь до .bin файла.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #12 : Октябрь 04, 2015, 18:16 »

Цитировать
Я бы хотел отделить сборку проекта и прошивку МК (по действию "Запустить" (Ctrl+R)). QBS позволяет такое сделать?

Наврятли.. Можешь почитать это: http://lists.qt-project.org/pipermail/qbs/2012-February/000025.html
возможно можно повесить что-нить на команду "qbs deploy", имею ввиду повесить скрипт который выполняет нужные вещи..

Ах, вспомнил, я еще спрашивал у них по подобной теме: мне нужно было выполнять сборку инсталлятора по отдельной команде.. т.е. я планировал ее на "qbs deploy" повесить.. т.е. "qbs build" - собирает проект, а "qbs deploy" - типа делает другое (собирает инсталлятор и прочее).

Но, кажется нифига это не работает: http://lists.qt-project.org/pipermail/qbs/2014-May/000765.html

UPD: Хм, а хотя, может уже и запилили кастомные таргеты: https://bugreports.qt.io/browse/QBS-262 .. нужно почитать.

UPD2: Воо, что-то есть: http://lists.qt-project.org/pipermail/qbs/2015-January/001166.html

Подмигивающий
« Последнее редактирование: Октябрь 04, 2015, 18:36 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
arhiv6
Гость
« Ответ #13 : Октябрь 10, 2015, 12:08 »

kuzulis, спасибо, кажется это то что мне нужно. Но, честно говоря, не очень понял, как использовать.  Необходимо для продукта указать свойство builtByDefault:false и добавить Transformer Item, в котором выполнять свою команду? Но ведь Transformer Item требует как минимум одного артефакта на выходе, а у меня в таком случае его не будет...
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #14 : Октябрь 10, 2015, 15:41 »

Вот, глянь сюда еще, я там задал вопрос: http://lists.qt-project.org/pipermail/qbs/2015-October/001455.html
Можешь в сорцах самого QBS (в его тестах и примерах) посмотреть как использовать это проперти.
Записан

ArchLinux x86_64 / Win10 64 bit
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.221 секунд. Запросов: 24.