реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Компиляция прошивки для дальнейшей загрузки bootlodaer'ом, Ошибка can't find ... words, после смещения кода
vovken1997
сообщение Mar 17 2016, 05:42
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 30-09-13
Пользователь №: 78 558



Здравствуйте!
Мне не удаётся скомпилировать прошивку для pic16f1825 компилятором xc8 (PRO mode) после того, как указываю codeoffset на 512 слов (в этой области загрузчик).
При обычной компиляции (без смещения) пишет 85% занято, бутлоадер занимает 7%.
Экспериментировал с различными значениями codeoffset, максимальное смещение при котором он ещё компилируется 340 слов, при чем если посмотреть код программы, то там остаётся куча незанятого места.

Есть ли какая нибудь возможность заставить компилятор скомпоновать код и создать hex со смещением.
Go to the top of the page
 
+Quote Post
Redguy
сообщение Mar 17 2016, 06:14
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 41
Регистрация: 14-01-10
Из: Россия, Самара
Пользователь №: 54 801



Для начала я бы ушел от процентного представления занятой памяти. Более точно все-таки в байтах в map-файле посмотреть сколько конкретно занимает ваша программа.
Второй момент нужно посмотреть linker файл после того, как вы установили смещение, убедиться, что смещение происходит действительно на нужное количество байт. А потом посмотреть чисто математически укладывается ли программа в предоставленный ей объем.

Самое главное: а ошибку-то какую получаете, ошибку компилятора или линковщика, какую конкретно?

Цитата
Есть ли какая нибудь возможность заставить компилятор скомпоновать код и создать hex со смещением.

Компилятор не компонует код, он только формиует рабочие куски кода с определенными входными аргументами, выходными параметрами, определенной длины. А вот линковщик уже эти готовые рабочие (100% проверенные) куски размещает в памяти по правилам заданным в линкер-файле и настраивает взаимосвязи между ними.

Сообщение отредактировал Redguy - Mar 17 2016, 06:19
Go to the top of the page
 
+Quote Post
vovken1997
сообщение Mar 17 2016, 19:36
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 30-09-13
Пользователь №: 78 558



Спасибо за ценный ответ. Посмотрел map при смещении на 150:
Код
               Name                               Link     Load   Length Selector   Space Scale
C:\Users\NIR\AppData\Local\Temp\s71g.obj
                end_init                            285      285        2      2A8       0
                reset_vec                           150      150        2      2A0       0
                config                             8007     8007        2    1000E       0
dist/default/production\medic.X.production.obj
                cinit                               951      951      6AF     12A2       0
                intentry                            154      154      131      2A8       0
                text54                              764      764       15      2A8       0
                text41                              287      287      4DD      2A8       0
                text12                              858      858       F9     10B0       0
                text11                             1990     1990      670     3320       0
                cstackBANK0                          20       20       33       20       1
                cstackCOMMON                         70       70        B       70       1
                clrtext                             779      779        C      2A8       0
                bssBANK2                            120      120       28      120       1
                bssBANK1                             A0       A0       46       A0       1
                dataBANK0                            6C       6C        4       20       1
                bssBANK0                             53       53       19       20       1
                bssCOMMON                            7B       7B        3       70       1
                stringtext                         1000     1000      6BE       20       0

Код
Psect      | Contents                       | Memory Range  | Size
------------|--------------------------------|---------------|--------------
            |                                |               |              
reset_vec  | Reset vector                   | 0150h - 0151h |    2 words  
intentry   | Interrupt context entry code   | 0154h - 0284h |  305 words  
end_init   | Initialization code            | 0285h - 0286h |    2 words  
text41     | Program and library code       | 0287h - 0763h | 1245 words  
text54     | Program and library code       | 0764h - 0778h |   21 words  
clrtext    | Memory clearing code           | 0779h - 0784h |   12 words  
text12     | Program and library code       | 0858h - 0950h |  249 words  
cinit     Microchip MPLAB XC8 C Compiler (PRO Mode) V1.33

Код
Program space:
    CONST                used     0h (     0) of  1EB0h words   (  0.0%)
    CODE                 used  144Bh (  5195) of  1EB0h words   ( 66.1%)
    STRCODE              used   6BEh (  1726) of  1EB0h words   ( 22.0%)
    ENTRY                used     0h (     0) of  1EB0h words   (  0.0%)
    STRING               used     0h (     0) of  1EB0h words   (  0.0%)

Код
Memory Summary:
    Program space        used  1B09h (  6921) of  2000h words   ( 84.5%)...


Видно, что смещение происходит и на нужную величину. Так же памяти у него достаточно, около 1000 слов, а надо всего 512.
Настораживает строчка:
Код
hlink "--edf=C:\Program Files (x86)\Microchip\xc8\v1.33\dat\en_msgs.txt" -cs -h+dist/default/production\medic.X.production.sym --cmf=dist/default/production\medic.X.production.cmf -z -Q16F1825 -oC:\Users\NIR\AppData\Local\Temp\s8m8.6 -Mdist/default/production/medic.X.production.map -ver=XC8#PRO##V1.33 -ASTACK=020C8h-0225fh -pstack=STACK -ACONST=0150h-01FFh,0200h-02FFhx30 -ACODE=0150h-07FFh,0800h-0FFFhx3 -ASTRCODE=0150h-01FFFh -AENTRY=0150h-01FFh,0200h-02FFhx30 -ASTRING=0150h-01FFh,0200h-02FFhx30 -ACOMMON=070h-07Fh -ABANK0=020h-06Fh -ABANK1=0A0h-0EFh -ABANK2=0120h-016Fh -ABANK3=01A0h-01EFh -ABANK4=0220h-026Fh -ABANK5=02A0h-02EFh -ABANK6=0320h-036Fh -ABANK7=03A0h-03EFh -ABANK8=0420h-046Fh -ABANK9=04A0h-04EFh -ABANK10=0520h-056Fh -ABANK11=05A0h-05EFh -ABANK12=0620h-064Fh -ABIGRAM=02000h-023EFh -ARAM=020h-06Fh,0A0h-0EFh,0120h-016Fh,01A0h-01EFh,0220h-026Fh,02A0h-02EFh,0320h-036Fh,03A0h-03EFh,0420h-046Fh,04A0h-04EFh,0520h-056Fh,05A0h-05EFh,0620h-064Fh -AABS1=020h-07Fh,0A0h-0EFh,0120h-016Fh,01A0h-01EFh,0220h-026Fh,02A0h-02EFh,0320h-036Fh,03A0h-03EFh,0420h-046Fh,04A0h-04EFh,0520h-056Fh,05A0h-05EFh,0620h-064Fh -ASFR0=00h-01Fh -ASFR1=080h-09Fh -ASFR2=0100h-011Fh -ASFR3=0180h-019Fh -ASFR4=0200h-021Fh -ASFR5=0280h-029Fh -ASFR6=0300h-031Fh -ASFR7=0380h-039Fh -ASFR8=0400h-041Fh -ASFR9=0480h-049Fh -ASFR10=0500h-051Fh -ASFR11=0580h-059Fh -ASFR12=0600h-061Fh -ASFR13=0680h-06EFh -ASFR14=0700h-076Fh -ASFR15=0780h-07EFh -ASFR16=0800h-086Fh -ASFR17=0880h-08EFh -ASFR18=0900h-096Fh -ASFR19=0980h-09EFh -ASFR20=0A00h-0A6Fh -ASFR21=0A80h-0AEFh -ASFR22=0B00h-0B6Fh -ASFR23=0B80h-0BEFh -ASFR24=0C00h-0C6Fh -ASFR25=0C80h-0CEFh -ASFR26=0D00h-0D6Fh -ASFR27=0D80h-0DEFh -ASFR28=0E00h-0E6Fh -ASFR29=0E80h-0EEFh -ASFR30=0F00h-0F6Fh -ASFR31=0F80h-0FEFh -preset_vec=0150h,intentry=0154h,init,end_init -ppowerup=CODE -pcinit=CODE -pfunctab=CODE -ACONFIG=08007h-08008h -pconfig=CONFIG -DCONFIG=2 -AIDLOC=08000h-08003h -pidloc=IDLOC -DIDLOC=2 -AEEDATA=00h-0FFh/0F000h -peeprom_data=EEDATA -DEEDATA=2 -DCODE=2 -DSTRCODE=2 -DSTRING=2 -DCONST=2 -DENTRY=2 -k C:\Users\NIR\AppData\Local\Temp\s8m8.obj dist/default/production\medic.X.production.obj


А именно -ACODE=0150h-07FFh,0800h-0FFFhx3 -ASTRCODE=0150h-01FFFh. Почему то класс кода делится на сегменты, один от 150 до 800, а остальные по 2к. слова далее до конца. При смещении на 200, линковщик после выше указанного текста hlink... выдаёт ошибку 0: (1347) can't find 0x58F words (0x58f withtotal) for psect "text41" in class "CODE" (largest unused contiguous range 0x493). Да, после изменения смещения параметр в линковщике меняется на -ACODE=0200h-07FFh,0800h-0FFFhx3.

К сожалению я не знаю, возможно ли вручную задать -ACODE=0200h-1FFF и будет ли это иметь какой то смысл, но это единственная моя догадка на данный момент. Если не сложно, подскажите пожалуйста.

Добавлено:
Нашёл такой текст в документации:
Цитата
The second cause of this message is when the total amount of memory needed by the
psect being positioned is sufficient, but that this memory is fragmented in such a way
that the largest contiguous block is too small to accommodate the psect. The linker is
unable to split psects in this situation. That is, the linker cannot place part of a psect at
one location and part somewhere else. Thus, the linker must be able to find a contiguous
block of memory large enough for every psect. If this is the cause of the error, then
the psect must be split into smaller psects if possible.
To find out what memory is still available, generate and look in the map file, see
Section 4.8.8 “-M: Generate Map File” for information on how to generate a map file.
Search for the string UNUSED ADDRESS RANGES. Under this heading, look for the
name of the segment specified in the error message. If the name is not present, then
all the memory available for this psect has been allocated. If it is present, there will be
one address range specified under this segment for each free block of memory. Determine
the size of each block and compare this with the number of words specified in the
error message.
Psects containing code can be reduced by using all the compiler’s optimizations, or
restructuring the program. If a code psect must be split into two or more small psects,
this requires splitting a function into two or more smaller functions (which may call each
other). These functions may need to be placed in new modules.
Psects containing data may be reduced when invoking the compiler optimizations, but
the effect is less dramatic. The program may need to be rewritten so that it needs less
variables. If the default linker options must be changed, this can be done indirectly
through the driver using the driver -L- option, see Section 4.8.7 “-L-: Adjust Linker
Options Directly”. Section 4.8.8 “-M: Generate Map File” has information on interpreting
the map file’s call graph if the compiler you are using uses a compiled stack. (If
the string Call graph: is not present in the map file, then the compiled code uses a
hardware stack.) If a data psect needs to be split into smaller psects, the definitions for
variables will need to be moved to new modules or more evenly spread in the existing
modules. Memory allocation for auto variables is entirely handled by the compiler.
Other than reducing the number of these variables used, the programmer has little control
over their operation. This applies whether the compiled code uses a hardware or
compiled stack.

На сколько я понимаю, предлагается разбивать функции или же редактировать параметры линковщика.
Я изменил параметр линковщика на -L-ACODE=0200h-07FFh,800h-1FFFh (это вставил в Additional option в настройках проекта XC8 Linker). В map файле проверил что установил правильно, проект скомпилировался. Когда добавил смещение, то получил новую ошибку: 1297: (1357) fixup overflow storing 0x92D in 2 bytes at 0x3254/0x2 -> 0x192A (dist/default/production\medic.X.production.obj 232/0x24)

Что это то такое?

Сообщение отредактировал vovken1997 - Mar 17 2016, 21:22
Go to the top of the page
 
+Quote Post
varostov
сообщение Mar 18 2016, 05:50
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 5-04-10
Из: Ростов-на-Дону
Пользователь №: 56 418



Здравствуйте! В своё время сам мучился с бутлоадером, требующим сдвига кода. В конце концов перебрался на загрузчик, который прописывается "на чердаке" программной памяти, позволяя отлаживать и компилировать программу так, как будто бутлоадера нет вовсе, а позже загружать полученный hex через бутлоадер. Могу порекомендовать популярный и хорошо документированный ds30Loader: Home page, Исходники. За пару вечеров изучил и запустил под PIC24. Не обращайте внимание на название, в исходниках коды на ассемблере для PIC12, 16, 18, 24, dsPIC, PIC32 + GUI под Windows (включая консольную версию).

P.S. GUI достаточно гибкое и позволяет настраивать, помимо прочего, скорость загрузки (включая autobaud) и способ сброса для загрузки - ручной, по сигналам DTR/RTS, по спец. команде (я, например, вбил модбасовскую команду дистанционного сброса устройства).


Сообщение отредактировал varostov - Mar 18 2016, 06:14
Go to the top of the page
 
+Quote Post
vovken1997
сообщение Mar 18 2016, 07:15
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 30-09-13
Пользователь №: 78 558



varostov, к сожалению размещать загрузчик "на чердаке" я не могу, так как эта область не защищается аппаратно и я использую прерывания, которые бы не хотелось передавать через программу.
Загрузчик я писал сам из-за достаточно уникальной задачи.
Go to the top of the page
 
+Quote Post
varostov
сообщение Mar 19 2016, 06:37
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 5-04-10
Из: Ростов-на-Дону
Пользователь №: 56 418



Ok, тогда желаю успеха. Подсказать, к сожалению, ничего не смогу (давно это было). На будущее: в PIC24 можно задавать количество защищаемых страниц с начала или конца программной памяти + другие фичи ("CodeGuard Security"). Что-то внедрено и в PIC18, но точно не изучал.
Go to the top of the page
 
+Quote Post
vovken1997
сообщение Mar 19 2016, 10:39
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 30-09-13
Пользователь №: 78 558



Спасибо!
Вчера пытался разбить на 20 подфункций. Ничего не получилось, все также ошибка при смещении...

Неужели ни у кого не было такой проблемы???
Go to the top of the page
 
+Quote Post
zltigo
сообщение Mar 19 2016, 19:22
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (varostov @ Mar 18 2016, 07:50) *
Здравствуйте! В своё время сам мучился с бутлоадером, требующим сдвига кода. В конце концов перебрался на загрузчик, который прописывается "на чердаке" программной памяти, позволяя отлаживать и компилировать программу так, как будто бутлоадера нет вовсе, а позже загружать полученный hex через бутлоадер.

Дела давно минувших дней... Когда делал загрузчик, для PIC16, то он у меня грузил программу сделанную "так, как будто бутлоадера нет вовсе". Только и сам был, как "обычная программа". Я пиками практчески не занимаюсь, так что разных кошерных загрузчиков не изучал за ненедобностью, а сделал, как сделал sm.gif.
Всего делов-то и было, что в нем по вектору сброса были 4 NOP, а при загрузке "программы" он слегка правил образ:
CODE
void main(void)
{

.....
.....


#asm
global _application_reset_vector
_application_reset_vector
       nop
       nop
       nop
       nop
#endasm
    // Wait watchdog in case the first four bytes are not a jmp instruction
    for(;; );
}




--------------------

                // The bootloader remaps the first four bytes of the application code into a secondary area.
                // This is done to preserve the initial reset vector that jumps to the bootloader.
                // By doing this, we make sure that the bootloader always fires up before the application
                // code and passes control onto it.
                  if( uhf.cdd_st.address < 0x0004 )
                {    // Remap the reset vector
                    byte len = uhf.cdd_st.len_u8 + uhf.cdd_st.address;
                    if( len > 4 )
                       len = 4;
                    len -= uhf.cdd_st.address;
                    // Write whatever part of the reset vector into our reserved appication_reset_vector.
                    // Write the remaining bytes into their original location.

                    if( flash_block_write( (ushort)&application_reset_vector + uhf.cdd_st.address, uhf.cdd_st.data_word, len )||
                        flash_block_write( uhf.cdd_st.address+len, &uhf.cdd_st.data_word[len], uhf.cdd_st.len_u8-len ) )
                       {



--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
vovken1997
сообщение Mar 20 2016, 17:07
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 30-09-13
Пользователь №: 78 558



Да, хороший способ. Но очень ненадежный...

Не защищены ни первые четыре слова, ни последние. Если сломался загрузчик у человека, у которого нет программатора, устройство можно выкинуть...
Go to the top of the page
 
+Quote Post
zltigo
сообщение Mar 20 2016, 17:40
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (vovken1997 @ Mar 20 2016, 19:07) *
Если сломался загрузчик у человека, у которого нет программатора, устройство можно выкинуть...

Это ужасно. У меня очевидно по незнанию sm.gif и такой живет с 2007 года в 40 тысячах с гаком экземпляров не выключаясь никогда.
Загрузчик и прошивка делалась для уже готовых, устройств одной юаровской фирмы, которые будучи поставлены на обьект в количестве пары тысяч штук, действительно окирпичивались в темпе 10 штук в день.
А что такое ломающийся загрузчик?. Или, скажем так, не ломающийся sm.gif?


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
vovken1997
сообщение Mar 21 2016, 19:55
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 30-09-13
Пользователь №: 78 558



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

Делается такая защита при помощи конфигурационных бит, которые указываются при прошивке программатором. Эти биты защищают какую то часть программы от перезаписи самой программой. Например в pic16f1825 можно либо вообще не защитить, либо защитить 0x200, либо 0x1000, либо всю. У меня стоит защита 0x200, следовательно первые 512 слов сама программа не может перезаписать. Это отдельно проверял, команды на стирание отправляются, а страница остаётся невредима.

Но тем ни менее моя проблема так и не решена! Есть загрузчик, но нет возможности сделать прошивку.
Столько про эти загрузчики разговоров в сети, неужели никто не загружал код, который занимает много памяти?
Go to the top of the page
 
+Quote Post
vovken1997
сообщение Mar 24 2016, 21:12
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 30-09-13
Пользователь №: 78 558



Прошивка скомпилировалась и слинковалась!
Компилятор: XC8 v1.37 (PRO mode) - бесплатная лицензия от Microchip на 60 дней
Среда разработки: MPLAB X IDE v3.25

Проблема была в том, что память в этом микроконтроллере разделена на 4 страницы, каждая страница 2К слова (если нужно перейти по адресу, находящемуся на другой странице, то необходима дополнительная команда смены страницы). Компилятор подготавливает так называемые psect (раздел памяти) в которых объединены функции. Если я правильно понимаю, то это такие своеобразные "чёрные ящики", которые компилятор отдаёт линковщику в виде объектных файлов, чтобы тот их разместил в памяти. Так как эти объектные файлы не могут находиться на стыке двух страниц, то есть пересекать их, то может возникнуть ситуация, когда памяти вроде бы хватает, но линковщик отказывается размещать "чёрные ящики", говоря, что максимальная не занятая область внутри страниц меньше, чем то, что необходимо разместить.

Следовательно чтобы решить данную проблему, необходимо разбить "чёрные ящики" на части. Я это сделал при помощи спецификатора __section(), который добавил у больших функций, чтобы компилятор подготовил для них отдельный psect и линковщик мог разместить их в памяти по своему желанию.

Да, при использовании данного метода, у меня съелось около 160 слов. Они были использованы компилятором для смены страниц при переходах.

Собственно вот пример:
Код
void __section("main") main (void) {
...
}

byte __section("settings") my_settings(byte mod){
...
}


Ну и позволю себе привести цитату из документации на компилятор:
Цитата
The __section() specifier may be used to indicate that an object should be located
in the named section (or psect, using the XC8 terminology). This is typically used when
the object has special and unique linking requirements which cannot be addressed by
existing compiler features.
Use the native keywords discussed in the Differences section to look up information on
the semantics of this specifier.
2.5.13.1 EXAMPLE
The following shows a variable which uses the __section keyword.
int __section("comSec") commonFlag;
2.5.13.2 DIFFERENCES
The 8-bit compilers have used the #pragma psect directive to redirect objects to a
new section, or psect. The operation of the __section() specifier is different to this
pragma in several ways, described below.
Unlike with the pragma, the new psect created with __section() does not inherit the
flags of the psect in which the object would normally have been allocated. This means
that the new psect can be linked in any memory area, including any data bank. The
compiler will also make no assumptions about the location of the object in the new section.
Objects redirected to new psects using the pragma must always be linked in the
same memory area, albeit at any address in that area.
The __section() specifier allows objects that are initialized to be placed in a different
psect. Initialization of the object will still be performed even in the new psect. This will
require the automatic allocation of an additional psect (whose name will be the same
as the new psect prefixed with the letter i), which will contain the initial values. The
pragma cannot be used with objects that are initialized.
Objects allocated a different psect with __section() will be cleared by the runtime
startup code, unlike objects which use the pragma.
You must reserve memory, and locate via a linker option, for any new psect created with
a __section() specifier in the current XC8 compiler implementation.
The 16- and 32-bit compilers have used the section attribute to indicate a different
destination section name. The __section() specifier works in a similar way to the
attribute.


Если кто то знает другое решение данной проблемы, прошу сообщить мне об этом.

Спасибо большое за помощь zltigo и остальным!
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd August 2017 - 16:51
Рейтинг@Mail.ru


Страница сгенерированна за 0.01471 секунд с 7
ELECTRONIX ©2004-2016