Отговори на тема  [ 24 мнения ]  Отиди на страница 1, 2  Следваща
Преход boоtloader към главна програма, и двете писани на C? 
Автор Съобщение
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Нед Ное 16, 2008 12:16 pm
Мнения: 174
Местоположение: София
Мнение Преход boоtloader към главна програма, и двете писани на C?
Здравейте,

Въпросът ми е за PIC16F и C - как да осигуря приемственост при предаване на управлението от bootloader-a към главната програма.
Написал съм си bootloader-а и главната програма, и двете на C, като ползвам Microchip-ския компилатор (XC8 1.31 ако е от значение). Bootloader-ът е тежък, щото искам да наливам ъпдейтите криптирани, да има чексуми и едва съм го сбил в 1200 думи. PIC-ът е 16F1704 - midrange, с 4096 думи памет.

Заделил съм bootloader-а да заема адреси 0x0 - 0x4ff, а главната програма е 0x500-0xfff. На линкера съм задал ROM range-ве респективно, а за главната програма - и codeoffset. Проверил съм, че hex-овете са както може да ги очаква човек.

Проблемът е при предаването на управлението от Bootloader-а към главната. Явно я оставя в някакво нечисто състояние и главната програма прави глупости и се държи странно.

Bootloader-ът засега прави следното: известно време слухти по I2C и ако нищо не се случи му доскучава и скача на 0x500. Скокът е обикновено GOTO. Не ползвам прекъсвания в Bootloader-a и съм направил interrupt forwarding. Главната програма тръгва, интеръптите ѝ работят (това беше една от мотиките - понеже Call-овете са с 11 битови литерали, но адресното пространство е 12-битово, не може просто да забиеш GOTO 0x504 на адрес 0x4 - трябва първо да зачистиш PCLATH). Обаче видно е нещо омазано, примерно едно от I2C съобщенията ми е нещо като статус от PIC-а, той отговаря, правилната дължина пакет праща, но смята грешно чексумата. Вероятно литералите за чексумирането му са грешни или де да знам. Нямам дебъгер да видя какво точно става.

Та към опитните пикоборци, как си осигурявате приемственост при този преход от едната програма към другата? Какви мотики може да има, за които не съм се сетил? Моето подозрение е, че компилаторът се прави на хитър и разчита на това конкретни променливи и адреси да са занулени като за след ресет, а те не са ... как мога да му подшушна "тая RAM не е девствена, вземай предпазни мерки" :butthead: ? Включил съм зануляването на BSS, разбира се.

И още:
- Има ли разлики между различните видове ресет, обикновената инструкция RESET извежда ли PIC-а в чисто състояние?
- Имам идея как да не мърся по стейта - ако помня някъде един бит дали при ресет да скачам директно към главната програма, или да стоя само в bootloader-а. Така почти нищо няма да пипна преди да направя скока към 0x500. Ако искам съвсем нищо да не пипна, трябва да сложа проверката и jump кода съвсем в началото - преди main(). Обаче не знам това как се прави?
- Има ли някъде подробен наръчник как трябва да се настрои toolchain-а точно за тоя случай и за XC8? Аз следвах примерно AN1302, ама той е ламерски, доста повърхностно описват всичко и примерно мотиката с PCLATH за interrupt forwarding-а не са я писали, само на картинката си личи, че знаят за нея и това имат предвид :)

Сори :) много въпроси :oops:

_________________
2 + 2 = 5, при много големи стойности на 2.


Вто Юни 20, 2017 3:40 pm
Профил ICQ WWW
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Вто Фев 06, 2007 1:45 am
Мнения: 260
Мнение Re: Преход boоtloader към главна програма, и двете писани на
...


Последна промяна tolstolob на Вто Юни 20, 2017 4:08 pm, променена общо 1 път



Вто Юни 20, 2017 4:00 pm
Профил
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Вто Фев 06, 2007 1:45 am
Мнения: 260
Мнение Re: Преход boоtloader към главна програма, и двете писани на
anrieff написа:
...Ако искам съвсем нищо да не пипна, трябва да сложа проверката и jump кода съвсем в началото - преди main(). Обаче не знам това как се прави?

Трябва да имплементираш 'powerup.s' (на асемблер). Можеш от него да си извикаш С функцията, дето прави проверката и после са обикновени джъмпове. Трябва да има темплейт (за powerup.s) из директориите на XC-то.


Вто Юни 20, 2017 4:07 pm
Профил
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Нед Ное 16, 2008 12:16 pm
Мнения: 174
Местоположение: София
Мнение Re: Преход boоtloader към главна програма, и двете писани на
Мерси, ще разгледам!
То нали писането на тоя powerup.s (аз сигурно ще си го реализирам цялото на асемблер, няма нужда от C функция) не отменя нищо от стандартната инициализация? Демек ако реша да си остана в буутлоудъра просто нищо не правя и то си продължава както си е стандартно?

_________________
2 + 2 = 5, при много големи стойности на 2.


Вто Юни 20, 2017 4:11 pm
Профил ICQ WWW
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Вто Фев 06, 2007 1:45 am
Мнения: 260
Мнение Re: Преход boоtloader към главна програма, и двете писани на
Това е hook, който се изпълнява веднага след ресет и преди С-стартъп кода.


Последна промяна tolstolob на Вто Юни 20, 2017 4:20 pm, променена общо 1 път



Вто Юни 20, 2017 4:13 pm
Профил
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Вто Фев 06, 2007 1:45 am
Мнения: 260
Мнение Re: Преход boоtloader към главна програма, и двете писани на
anrieff написа:
... трябва първо да зачистиш PCLATH...

Тук нещо мирише... А ако трябва да се вика нещо на адрес над 0х7FF ?


Вто Юни 20, 2017 4:18 pm
Профил
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Нед Ное 16, 2008 12:16 pm
Мнения: 174
Местоположение: София
Мнение Re: Преход boоtloader към главна програма, и двете писани на
Е как - вдигаш съответните битове на PCLATH :) Има си даже инструкция която зарежда литерал в него, с нея реализират няколкото макроса, които имат за "далечни" разклонения (ljmp, lcall). В генерирания код от компилатора гъмжи от тях.

_________________
2 + 2 = 5, при много големи стойности на 2.


Вто Юни 20, 2017 9:58 pm
Профил ICQ WWW
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 07, 2012 10:22 pm
Мнения: 3074
Мнение Re: Преход boоtloader към главна програма, и двете писани на
Пърият (ти) въпрос е - лоадера ли омазва нещо или има гешка в основната програма.
Като мине нулирането на РАМ в началото на лоадера- предай упрвлението на главната , без да пипаш никакви регистри.
После пак ще мислиш.


Сря Юни 21, 2017 6:50 am
Профил
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Нед Ное 16, 2008 12:16 pm
Мнения: 174
Местоположение: София
Мнение Re: Преход boоtloader към главна програма, и двете писани на
stefan63, омазването беше в основната програма, bootloader-ът работи.

Аз вчера го поборих още и май го оправих.
Значи основната част от омазването беше едно нещо по I2C-то, което не работеше като трябва. И се оправи, когато в bootloader-а, точно преди да предам контрола на главната програма, нулирам обратно всички регистри за MSSP периферията към началните им стойности. Скандалното е, че това би следвало да е ненужно, щото тя главната програма малко след това връща почти същите стойности като при bootloader, само I2C адресът е различен. Обаче с този фикс се оправи, не съм се занимавал да проверявам кой регистър от всичките прави проблема.
А по омазването с грешната чексума се оказа фалшива тревога, бъгът се оказа на съвсем друго място, в I2C мастъра.

Проблемът е решен, отбой засега :)

_________________
2 + 2 = 5, при много големи стойности на 2.


Сря Юни 21, 2017 5:00 pm
Профил ICQ WWW
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Вто Фев 06, 2007 1:45 am
Мнения: 260
Мнение Re: Преход boоtloader към главна програма, и двете писани на
И накрая да обобщим:
1. Желателно е Init()-а на всеки периферен драйвер да инитва стойностите на всички статични променливи, които ползва, вместо да разчита на стартъп кода.
2. Хубаво е всеки периферен драйвер да експортва и DeInit() функция.


Сря Юни 21, 2017 5:08 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 07, 2012 10:22 pm
Мнения: 3074
Мнение Re: Преход boоtloader към главна програма, и двете писани на
На 3,5 килодуми е трудно да се говори за драйвер.


Сря Юни 21, 2017 5:45 pm
Профил
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Нед Ное 16, 2008 12:16 pm
Мнения: 174
Местоположение: София
Мнение Re: Преход boоtloader към главна програма, и двете писани на
stefan63 написа:
На 3,5 килодуми е трудно да се говори за драйвер.

Хаха, ти да видиш.. аз буутлоудъра в началото го бях събрал в 1190 думи (от които 300 са само криптирането), и си викам - бре даже артисват 80-на думи, ако потрябва. Че като дебъгвам е полезно. Обаче днеска нова тесла... там като получа поредния блок за флашване, съм го направил да clock-stretch-ва докато го дешифрира и записва, и връщам nack, ако записването не стане или не излезне чексумата. Да, обаче декриптирането отнема 18ms, записа още 2 и през това време на мастъра му омръзва да го чака, нищо че PIC-а накрая си ack-ва като пич. Та сега ще трябва да реорганизирам логиката да ack-ва бързо за да освободи шината, а аз да си чексумвам след това и да връщам статус със отделно съобщение. Не е много играчка, ама да видиш гювеча как бързо ще свърши, че може и да не стигне :)

_________________
2 + 2 = 5, при много големи стойности на 2.


Сря Юни 21, 2017 6:51 pm
Профил ICQ WWW
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Вто Фев 06, 2007 1:45 am
Мнения: 260
Мнение Re: Преход boоtloader към главна програма, и двете писани на
stefan63 написа:
На 3,5 килодуми е трудно да се говори за драйвер.

Следното нещо се компилира до ~200 думи:
http://kae-systems.com/CodeExamples/PIC18/Drivers/EEPROM_Onchip/EEP_drv_int.c
и си е баш периферен драйвер.


Сря Юни 21, 2017 7:33 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 07, 2012 10:22 pm
Мнения: 3074
Мнение Re: Преход boоtloader към главна програма, и двете писани на
Драйвер може да наречеш всяко нещо, зависи от гледната точка.
"Този драйвер не поддържа тази функция" - обикновено се кодира с едно 16 битово число -"404" да речем :) .
Та заедно с ретърна - около 2-3 думи. Не се заяждамс никого , просто споделям мнение :)


Сря Юни 21, 2017 7:45 pm
Профил
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Нед Ное 16, 2008 12:16 pm
Мнения: 174
Местоположение: София
Мнение Re: Преход boоtloader към главна програма, и двете писани на
Да допълня как завърши сагата при мен - щото уж

anrieff написа:
Проблемът е решен, отбой засега :)


ама това беше на първи прочит. На втори се оказва, че все още се омазва нещо по главната програма, даже и след поправките да зачиства регистрите на MSSP-то.

Накратко, реализирах подхода със powerup.as и магическия бит в паметта, който да указва дали да буутвам в лоудъра, или да скачам на главната програма.

По-подробно - моят чип е с 4096 думи, с адреси 0..0x0fff. Разделен е на 3 области - 0..0x4ff e bootloader, 0x500..0xfdf е главната програма, а 0xfe0..0xfff е страница за конфигурации, то това по принцип е последната страница от HEF блока.

На 0x4 имам interrupt forwarding към 0x504 (във вид MOVLP 0; GOTO 0x504). На 0xfe0 ми е магическият бит, по-точно там седи инструкция RETLW: ако е RETLW 0 - буутва директно в главната програма; ако е RETLW 1, влиза в буутлоудъра. Въпросната дума се вика от powerup.as, по този начин:

Код:
   lcall   0x0fe0
   andlw   1
   btfsc   STATUS, 2 ; test zero bit
   goto   0x500     ; or whatever codeoffset is


така че ако сме в режим "главна програма", наистина не пипаме нищо преди да ѝ сдадем контрола.

Понеже не знам дали мога да накарам компилатора и туулчейна да ми създадат такава сложна организация (е сигурно може, ама не ми се четеше), съм си написал скриптче, което снажда двата .hex-а (от bootloader и главната програма) и дописва още няколкото корекции (interrupt forward вектора и RETLW-то). Така флашвам завършена програма първоначално на пиците. RETLW-то е 0, така че главния процесор не му се налага да прави първоначално наливане на фърмуер.

Когато искам да ъпдейтна фърмуера, главният процесор прави следните неща:

1. По I2C-то казва на главната програма на PIC-а да си запише RETLW 1 на 0xfe0
2. Изкомандва ресет
3. Почва да си говори с буутлоудъра и налива новия софт. Като част от наливането, 0xfe0 се презаписва обратно с RETLW 0.
4. Нов ресет
5. Вече си говори с ъпдейтната главна програма

Като препоръка ако някой тръгне по тоя път - направете си симулатор! (при мене беше PC конзолна програма - емулирам MSSP регистрите като volatile глобални променливи, пускам кода на главния процесор в една нишка, кода на PIC-а в друга, и имах малко съединителен слой да емулира истинското желязо). Особено полезно е ако кодът е сложен и имате крипто. Просто има супер много неща, които може да се омажат по предаването на данните, чексумирането, криптото, верификацията, а ще са зверски трудни за дебъг. В крайна сметка симулатора го написах за ден, а спестих поне няколко дена дебъг :)

Фин де приказката, благодарности на tolstolob за насоката!

_________________
2 + 2 = 5, при много големи стойности на 2.


Чет Окт 12, 2017 2:15 am
Профил ICQ WWW
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 24 мнения ]  Отиди на страница 1, 2  Следваща

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 3 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни