Что может мешать выполнению кода в бутлоадере, если он же работает в основной программе? код с использованием SPI

В первом варианте прошиваю обычным способом из Иде по юарт . Фьюзы при этом FF DE FD В таком варианте кан работает.

Во втором варианте кладу готовый хекс загрузчика , который собирается gcc через командную строку. Он кладет код как надо по адресу начала загрузчика. Это в makefile настраивается (размер загрузчика). Данную процедуру делаю программатором по spi. По итоговым bin дампам я смотрел там все соответствует. Фьюзы FF D8 FD

папка , в ней хексы бины и листинги обоих вариантов

короче я вообще ничего не пойму
вот кусок кода функции mcp2515_init в комментах написал суть проблемы и ниже скрин лога

{

  uint8_t res;

    mcp2515_reset();
 //			  0x40   
    mcpMode = MCP_LOOPBACK;
//						              0x80
    res = mcp2515_setCANCTRL_Mode(MODE_CONFIG);  
    putch (res);  // отправим в отладку результат  mcp2515_setCANCTRL_Mode, по логу он==0
    if(res > 0) 
    {
putch (0x12);    // но какого хрена программа сюда заходит, если res ==0  ???
                 // этот 0х12 я вижу в логе , соответственно ниже срабатывает return
                 // и дальше инит не идет. 
      return res;
    }

byte res1 = 0;
res1 = mcp2515_configRate(canSpeed, canClock);
 
// Set Baudrate
    if(res1)

Попробуйте подождать.

 
    while(res = mcp2515_setCANCTRL_Mode(MODE_CONFIG));// или просто  nop добавить
    putch (res);  // отправим в отладку результат  mcp2515_setCANCTRL_Mode, 
    if(res > 0) 

может бред скажу, но где-то тут видимо оптимизатор вмешивается. или нужно inline или наоборот noinline функции объявлять

листинг этого места где коряво 0 проверяется

00007642 <_ZN7MCP_CAN12mcp2515_initEhhh>:
    7642:	ef 92       	push	r14
    7644:	ff 92       	push	r15
    7646:	0f 93       	push	r16
    7648:	1f 93       	push	r17
    764a:	cf 93       	push	r28
    764c:	df 93       	push	r29
    764e:	ec 01       	movw	r28, r24
    7650:	06 2f       	mov	r16, r22
    7652:	f4 2e       	mov	r15, r20
    7654:	e2 2e       	mov	r14, r18
    7656:	94 dd       	rcall	.-1240   	; 0x7180 <_ZN7MCP_CAN13mcp2515_resetEv>
    7658:	80 e4       	ldi	r24, 0x40	; 64
    765a:	89 8b       	std	Y+17, r24	; 0x11
    765c:	60 e8       	ldi	r22, 0x80	; 128
    765e:	ce 01       	movw	r24, r28
    7660:	23 de       	rcall	.-954    	; 0x72a8 <_ZN7MCP_CAN23mcp2515_setCANCTRL_ModeEh>
    7662:	18 2f       	mov	r17, r24
    7664:	25 dd       	rcall	.-1462   	; 0x70b0 <_Z5putchh>
    7666:	82 e1       	ldi	r24, 0x12	; 18
    7668:	11 11       	cpse	r17, r1
    766a:	07 c0       	rjmp	.+14     	; 0x767a <_ZN7MCP_CAN12mcp2515_initEhhh+0x38>
    766c:	4e 2d       	mov	r20, r14
    766e:	6f 2d       	mov	r22, r15
    7670:	ce 01       	movw	r24, r28
    7672:	37 de       	rcall	.-914    	; 0x72e2 <_ZN7MCP_CAN18mcp2515_configRateEhh>
    7674:	88 23       	and	r24, r24
    7676:	51 f0       	breq	.+20     	; 0x768c <_ZN7MCP_CAN12mcp2515_initEhhh+0x4a>
    7678:	83 e1       	ldi	r24, 0x13	; 19
    767a:	1a dd       	rcall	.-1484   	; 0x70b0 <_Z5putchh>
    767c:	81 2f       	mov	r24, r17
    767e:	df 91       	pop	r29
    7680:	cf 91       	pop	r28
    7682:	1f 91       	pop	r17
    7684:	0f 91       	pop	r16
    7686:	ff 90       	pop	r15
    7688:	ef 90       	pop	r14
    768a:	08 95       	ret
    768c:	84 e1       	ldi	r24, 0x14	; 20
    768e:	10 dd       	rcall	.-1504   	; 0x70b0 <_Z5putchh>
    7690:	ce 01       	movw	r24, r28
    7692:	7d df       	rcall	.-262    	; 0x758e <_ZN7MCP_CAN22mcp2515_initCANBuffersEv>
    7694:	43 e0       	ldi	r20, 0x03	; 3
    7696:	6b e2       	ldi	r22, 0x2B	; 43
    7698:	ce 01       	movw	r24, r28
    769a:	b0 dd       	rcall	.-1184   	; 0x71fc <_ZN7MCP_CAN19mcp2515_setRegisterEhh>
    769c:	4c e3       	ldi	r20, 0x3C	; 60
    769e:	6c e0       	ldi	r22, 0x0C	; 12
    76a0:	ce 01       	movw	r24, r28
    76a2:	ac dd       	rcall	.-1192   	; 0x71fc <_ZN7MCP_CAN19mcp2515_setRegisterEhh>
    76a4:	40 e0       	ldi	r20, 0x00	; 0
    76a6:	6d e0       	ldi	r22, 0x0D	; 13
    76a8:	ce 01       	movw	r24, r28
    76aa:	a8 dd       	rcall	.-1200   	; 0x71fc <_ZN7MCP_CAN19mcp2515_setRegisterEhh>
    76ac:	00 23       	and	r16, r16
    76ae:	a9 f0       	breq	.+42     	; 0x76da <_ZN7MCP_CAN12mcp2515_initEhhh+0x98>
    76b0:	03 30       	cpi	r16, 0x03	; 3
    76b2:	d1 f4       	brne	.+52     	; 0x76e8 <_ZN7MCP_CAN12mcp2515_initEhhh+0xa6>
    76b4:	24 e6       	ldi	r18, 0x64	; 100
    76b6:	44 e6       	ldi	r20, 0x64	; 100
    76b8:	60 e6       	ldi	r22, 0x60	; 96
    76ba:	ce 01       	movw	r24, r28
    76bc:	cf dd       	rcall	.-1122   	; 0x725c <_ZN7MCP_CAN22mcp2515_modifyRegisterEhhh>
    76be:	20 e6       	ldi	r18, 0x60	; 96
    76c0:	40 e6       	ldi	r20, 0x60	; 96
    76c2:	60 e7       	ldi	r22, 0x70	; 112
    76c4:	ce 01       	movw	r24, r28
    76c6:	ca dd       	rcall	.-1132   	; 0x725c <_ZN7MCP_CAN22mcp2515_modifyRegisterEhhh>
    76c8:	69 89       	ldd	r22, Y+17	; 0x11
    76ca:	ce 01       	movw	r24, r28
    76cc:	df 91       	pop	r29
    76ce:	cf 91       	pop	r28
    76d0:	1f 91       	pop	r17
    76d2:	0f 91       	pop	r16
    76d4:	ff 90       	pop	r15
    76d6:	ef 90       	pop	r14
    76d8:	e7 cd       	rjmp	.-1074   	; 0x72a8 <_ZN7MCP_CAN23mcp2515_setCANCTRL_ModeEh>
    76da:	24 e0       	ldi	r18, 0x04	; 4
    76dc:	44 e6       	ldi	r20, 0x64	; 100
    76de:	60 e6       	ldi	r22, 0x60	; 96
    76e0:	ce 01       	movw	r24, r28
    76e2:	bc dd       	rcall	.-1160   	; 0x725c <_ZN7MCP_CAN22mcp2515_modifyRegisterEhhh>
    76e4:	20 e0       	ldi	r18, 0x00	; 0
    76e6:	ec cf       	rjmp	.-40     	; 0x76c0 <_ZN7MCP_CAN12mcp2515_initEhhh+0x7e>
    76e8:	11 e0       	ldi	r17, 0x01	; 1
    76ea:	c8 cf       	rjmp	.-112    	; 0x767c <_ZN7MCP_CAN12mcp2515_initEhhh+0x3a>

а не может ли быть проблема в том , что загрузчик собирается компилятором g++, а исходник бутлоадера файл имеет расширение .c ?

Таблица прерываний с одними заглушками в первом случае и пустая во втором - следовательно и разрешать прерывания не надо …

Если заглянуть в эту функцию, то получается она сама ждет установки нового режима. Но если режим уже соответствует нужному, то сразу выход. Короче не самая правильная функция для отладки.

В примере у автора прерывания не используются ни одной функцией. так что побоку, разрешены или нет.

убрал классы, перевел код на С , скомпилировал уже как gcc , проблема не решилась.

uint8_t  mcp2515_init(const uint8_t canIDMode, const uint8_t canSpeed, const uint8_t canClock)
{

uint8_t res;
mcp2515_reset();
  
    mcpMode = MCP_LOOPBACK;

    res = mcp2515_setCANCTRL_Mode(MODE_CONFIG); 
  
    SPIbeginTransaction(10000000, MSBFIRST, SPI_MODE0);
    
    MCP2515_SELECT();          //  это я помимо отладки в UART (вдруг он неправильно выводит)
    spi_readwrite(res);        //  отправил в SPI байт 
    MCP2515_UNSELECT();        //  результат функции mcp2515_setCANCTRL_Mode
   // этот результат даже в SPI шине показывает 0 , 
   // но ниже условия не срабатывают, это жесть какая то 

   if ( res == false)  {putch (0x99);}
   if ( res == false)  {putch (res);}


    if(res > 0)
    {
putch (0x12);   // хоть ты тресни, но сюда все равно заходит и все, хотя res == 0
      return res;
    }
//бла бла
return res;

}

листинг

Спойлер

000074fe <mcp2515_init>:
74fe: 0f 93 push r16
7500: 1f 93 push r17
7502: cf 93 push r28
7504: df 93 push r29
7506: d8 2f mov r29, r24
7508: 16 2f mov r17, r22
750a: 04 2f mov r16, r20
750c: d8 dd rcall .-1104 ; 0x70be <mcp2515_reset>
750e: 80 e4 ldi r24, 0x40 ; 64
7510: 80 93 1e 01 sts 0x011E, r24 ; 0x80011e
7514: 80 e8 ldi r24, 0x80 ; 128
7516: 50 de rcall .-864 ; 0x71b8 <mcp2515_setCANCTRL_Mode>
7518: c8 2f mov r28, r24
751a: c6 dd rcall .-1140 ; 0x70a8 <SPIbeginTransaction.constprop.2>
751c: 2a 98 cbi 0x05, 2 ; 5
751e: 8c 2f mov r24, r28
7520: bc dd rcall .-1160 ; 0x709a
7522: 2a 9a sbi 0x05, 2 ; 5
7524: 82 e1 ldi r24, 0x12 ; 18
7526: c1 11 cpse r28, r1
7528: 0a c0 rjmp .+20 ; 0x753e <mcp2515_init+0x40>
752a: 89 e9 ldi r24, 0x99 ; 153
752c: af dd rcall .-1186 ; 0x708c
752e: 80 e0 ldi r24, 0x00 ; 0
7530: ad dd rcall .-1190 ; 0x708c
7532: 60 2f mov r22, r16
7534: 81 2f mov r24, r17
7536: 59 de rcall .-846 ; 0x71ea <mcp2515_configRate>
7538: 88 23 and r24, r24
753a: 19 f0 breq .+6 ; 0x7542 <mcp2515_init+0x44>
753c: 83 e1 ldi r24, 0x13 ; 19
753e: a6 dd rcall .-1204 ; 0x708c
7540: 26 c0 rjmp .+76 ; 0x758e <mcp2515_init+0x90>
7542: 84 e1 ldi r24, 0x14 ; 20
7544: a3 dd rcall .-1210 ; 0x708c
7546: 94 df rcall .-216 ; 0x7470 <mcp2515_initCANBuffers>
7548: 63 e0 ldi r22, 0x03 ; 3
754a: 8b e2 ldi r24, 0x2B ; 43
754c: ec dd rcall .-1064 ; 0x7126 <mcp2515_setRegister>
754e: 6c e3 ldi r22, 0x3C ; 60
7550: 8c e0 ldi r24, 0x0C ; 12
7552: e9 dd rcall .-1070 ; 0x7126 <mcp2515_setRegister>
7554: 60 e0 ldi r22, 0x00 ; 0
7556: 8d e0 ldi r24, 0x0D ; 13
7558: e6 dd rcall .-1076 ; 0x7126 <mcp2515_setRegister>
755a: dd 23 and r29, r29
755c: 89 f0 breq .+34 ; 0x7580 <mcp2515_init+0x82>
755e: d3 30 cpi r29, 0x03 ; 3
7560: a9 f4 brne .+42 ; 0x758c <mcp2515_init+0x8e>
7562: 44 e6 ldi r20, 0x64 ; 100
7564: 64 e6 ldi r22, 0x64 ; 100
7566: 80 e6 ldi r24, 0x60 ; 96
7568: 0a de rcall .-1004 ; 0x717e <mcp2515_modifyRegister>
756a: 40 e6 ldi r20, 0x60 ; 96
756c: 60 e6 ldi r22, 0x60 ; 96
756e: 80 e7 ldi r24, 0x70 ; 112
7570: 06 de rcall .-1012 ; 0x717e <mcp2515_modifyRegister>
7572: 80 91 1e 01 lds r24, 0x011E ; 0x80011e
7576: df 91 pop r29
7578: cf 91 pop r28
757a: 1f 91 pop r17
757c: 0f 91 pop r16
757e: 1c ce rjmp .-968 ; 0x71b8 <mcp2515_setCANCTRL_Mode>
7580: 44 e0 ldi r20, 0x04 ; 4
7582: 64 e6 ldi r22, 0x64 ; 100
7584: 80 e6 ldi r24, 0x60 ; 96
7586: fb dd rcall .-1034 ; 0x717e <mcp2515_modifyRegister>
7588: 40 e0 ldi r20, 0x00 ; 0
758a: f0 cf rjmp .-32 ; 0x756c <mcp2515_init+0x6e>
758c: c1 e0 ldi r28, 0x01 ; 1
758e: 8c 2f mov r24, r28
7590: df 91 pop r29
7592: cf 91 pop r28
7594: 1f 91 pop r17
7596: 0f 91 pop r16
7598: 08 95 ret

а скиньте полный проект, желательно не на яндекс, а что нить зарубежное.

А где обнуление R1 ? Где настройка стека ? Первые команды из первого листинга надо добавить во второй код !

По соглашению - компилятор считает что в R1 всегда 0 !

Перед CPSE выведите R1 в монитор и посмотрите с чем он сравнивает …

эмм , я в асме вообще не бум бум . Что значит настройка стека ?

Надо в регистры указателя стека поместить адрес вершины - иначе хз откуда мк начнет сохранять вызовы процедур и переменные …

Можно в самое начало через asm volatile добавить все 6 команд для обнуления r1 и задания вершины стека

1 лайк

пасиб, изучаю вопрос

а как тогда обычный бутлоадер работает? где там задано начало стека и обнуление r1 ?
похоже это в файле boot.h

Обычный собирается со стандартной шапкой:

  6a:	11 24       	eor	r1, r1
  6c:	1f be       	out	0x3f, r1	; 63
  6e:	cf ef       	ldi	r28, 0xFF	; 255
  70:	d8 e0       	ldi	r29, 0x08	; 8
  72:	de bf       	out	0x3e, r29	; 62
  74:	cd bf       	out	0x3d, r28	; 61

Но где она формируется я не помню …

1 лайк

это можно ассемблерной вставкой добавить куда то ?

Странно что оно автоматом не добавилось … вернее добавилось, но не полностью … что то надо где то прописать линкеру …

Шапка уже предсобрана и лежит где то по адресу …packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7\avr\lib\…

ИМХО можно в начало main положить … по листингу варианта в области загрузчика до main нет никаких движений затрагивающих стек - просто переменные копируются в озу …

1 лайк