Перейти к содержанию
    

Проблема при стирании страниц.

Есть бутлодер

Spoiler

unsigned char FC_Communication( void )
{
	uint8_t i,rd_buff[100]={0};
	uint8_t *pAddress;
	ADDRESS_TYPE * pTempAddress;
	static byte isFirstTime = 1;
	uint8 tempde=0;


	// read data from UART -----> We are reading the data through the interrupt UART_OnRxChar to uiReadData (Global parameter).

	status = UART_RecvChar(&uiReadData);

	if((status == ERR_RXEMPTY  )&&(g_ucFC_State != 0)) // if we don't get nothing in status & this is not first state return.
		return 0; // was: return 2


	switch( g_ucFC_State )
	{
		case FC_STATE_NULL:
		{
			if( uiReadData == FC_CMD_ACK )
			{
				UART_Send(0xFC);
				g_ucFC_State = FC_STATE_WORKING;
			}
			else
			{
				return 0;
			}
		}
		break;
		case FC_STATE_WORKING:
			{
				switch( uiReadData )
				{
					case FC_CMD_IDENT:
						{

							if(!isFirstTime) // To prevent sending all the time the strings to the host.
							{
								return 1;
							}


							UART_Send(m_MCU_Info.Version);
							UART_Send(m_MCU_Info.Sdid>>8);
							UART_Send(m_MCU_Info.Sdid);


							pTempAddress = (ADDRESS_TYPE *)&m_MCU_Info.BlocksCnt;
							for(i=0;i<7;i++)
							{

								UART_Send(pTempAddress[i].Bytes.hh);
								WAIT1_Waitus(10);

								UART_Send(pTempAddress[i].Bytes.hl);
								WAIT1_Waitus(10);

								UART_Send(pTempAddress[i].Bytes.lh);
								WAIT1_Waitus(10);

								UART_Send(pTempAddress[i].Bytes.ll);
								WAIT1_Waitus(10);

							}
							i = 0;
							do
							{
								UART_Send(m_MCU_Info.IdString[i]);
							}while(m_MCU_Info.IdString[i++]);

							isFirstTime = 0;


					}
					break;
					case FC_CMD_ERASE:
						{
							g_ucFC_State = FC_STATE_EREASE;
					}
					break;
					case FC_CMD_WRITE:
						{
							g_ucFC_State = FC_STATE_WRITE_ADDRESS;
					}
					break;
					case FC_CMD_READ:
						{
							g_ucFC_State = FC_STATE_READ;
					}
					break;
					case FC_CMD_QUIT:
						{
							 SCB_VTOR = RELOCATION_VERTOR_ADDR;
							 JumpToUserApplication(RELOCATION_VERTOR_ADDR);
					}
					break;

					default:
						break;
			}
			m_uiRecCount = 0;
			idx = 0;
		}
		break;

		case FC_STATE_EREASE:
			{
				m_pRecFrame[m_uiRecCount++] = uiReadData;
				if( m_uiRecCount >= sizeof(uint32_t) )
				{
					// erase
					LONG_Convert(&m_RecFrame.uiAddress);
					if(!Flash_EraseSector(m_RecFrame.uiAddress))
					{
						UART_Send(FC_CMD_ACK);
					}
					else
					{
						UART_Send(FC_CMD_NACK);
					}

					g_ucFC_State = FC_STATE_WORKING;
				}
		}
		break;
		case FC_STATE_WRITE_ADDRESS:
			{
				m_pRecFrame[m_uiRecCount++] = uiReadData;
				if( m_uiRecCount >= sizeof(uint32_t) )
				{
					g_ucFC_State = FC_STATE_WRITE_LEN;
				}

		}
		break;
		case FC_STATE_WRITE_LEN:
			{
				m_pRecFrame[m_uiRecCount++] = uiReadData;
                                g_ucFC_State = FC_STATE_WRITE_DATA;
		}
		break;
		case FC_STATE_WRITE_DATA:
			{
				m_pRecFrame[m_uiRecCount++] = uiReadData;
				if( m_uiRecCount > (m_RecFrame.Length + sizeof(uint32_t) ))
				{
					LONG_Convert(&m_RecFrame.uiAddress);
                    Memcpy_Byte((uint8_t *)&m_ucDataBuff[0],(uint8_t *)&m_RecFrame.DataBuff[0],m_RecFrame.Length);
			        uiNumberCount ++;


                    if( !Flash_Write(m_RecFrame.uiAddress,
				   (uint8_t *)&m_ucDataBuff[0],m_RecFrame.Length) )
					{
                    	UART_Send(FC_CMD_ACK);
					}
					else
					{
						UART_Send(FC_CMD_NACK);
					}

					g_ucFC_State = FC_STATE_WORKING;
				}
			}
			break;
		case FC_STATE_READ:
			{
				m_pRecFrame[m_uiRecCount++] = uiReadData;
				if( m_uiRecCount > sizeof(uint32_t) )
				{
					LONG_Convert(&m_RecFrame.uiAddress);
					pAddress = (uint8_t *)m_RecFrame.uiAddress;
					for( i=0;i<m_RecFrame.Length;i++)
					{
						UART_Send(pAddress[i]);
					}
					g_ucFC_State = FC_STATE_WORKING;
				}
		}
		break;
		default:
			break;
		}
	return 1;
}

 

Главная програма начинается по адресу 0х4000. Перед записью главной програмы хочу стереть все страницы.Посылаю opcode erase + address.

Первая посылка - FC_CMD_ERASE  4000 - if(!Flash_EraseSector(m_RecFrame.uiAddress)) возвращает FC_CMD_ACK - всё хорошо, страница стерта.

Вторая посылка - FC_CMD_ERASE  5000 (page size 0x1000) - на  if(!Flash_EraseSector(m_RecFrame.uiAddress)) попадаю в исключение

PE_ISR(Cpu_Interrupt)
{
/* This code can be changed using the CPU component property "Build Options / Unhandled int code" */
PE_DEBUGHALT();
}

В чём проблема?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 минут назад, jenya7 сказал:

В чём проблема?

А какой микроконтроллер? Что это за исключение PE_ISR(Cpu_Interrupt)?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, MrBearManul said:

А какой микроконтроллер? Что это за исключение PE_ISR(Cpu_Interrupt)?

Kinetis MK10F12. Это обертка но я думаю Hard Fault. Call Stack не работает, не могу отследить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 минут назад, jenya7 сказал:

Это обертка но я думаю Hard Fault.

Блин, когда же авторы сами-то начнут писать свой код?)) Тогда и говорить хоть о чём-то можно. Думаю, что ваша ошибка связана с выравниванием данных, либо попыткой выполнить код из флешки, которая в этот момент записывается.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 hours ago, MrBearManul said:

Блин, когда же авторы сами-то начнут писать свой код?)) Тогда и говорить хоть о чём-то можно. Думаю, что ваша ошибка связана с выравниванием данных, либо попыткой выполнить код из флешки, которая в этот момент записывается.

ну я вобщем то не ограничиваю размер бутлоадера.

бутлоадер находится по адресу

m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x000001E8

m_text    (RX) : ORIGIN = 0x00000410, LENGTH = 0x000FFBF0

может надо ограничить LENGTH до 0х3FFF?

Их утилита работает. На команду ERASE стирает все страницы.

 

попробовал так

 

FC_CMD_ERASE  5000  - FC_CMD_ACK

FC_CMD_ERASE  5000  - FC_CMD_ACK

FC_CMD_ERASE  4000 - PE_ISR(Cpu_Interrupt)

 

не пойму что за хрень такая. падает на

 

FTFE_PDD_EnableInterrupts(FTFE_BASE_PTR, FTFE_PDD_COMMAND_COMPLETE_INT); /* Enable the Command complete interrupt */

в

LDD_TError IntFlashLdd1_Erase(LDD_TDeviceData *DeviceDataPtr, LDD_FLASH_TAddress FromAddress, LDD_FLASH_TDataSize Size)
{
  IntFlashLdd1_TDeviceDataPtr DeviceDataPrv = (IntFlashLdd1_TDeviceDataPtr)DeviceDataPtr; /* Auxiliary variable - pointer to an internal state structure */
  uint32_t EraseUnitMask;
  
  if (!(DeviceDataPrv->CurrentOperationStatus == LDD_FLASH_IDLE) && /* If some operation is already in progress return error. */\
     !(DeviceDataPrv->CurrentOperationStatus == LDD_FLASH_STOP) && \
     !(DeviceDataPrv->CurrentOperationStatus == LDD_FLASH_FAILED)) {
    return ERR_BUSY;
  }
  EraseUnitMask = IntFlashLdd1_PFLASH_ERASABLE_UNIT_SIZE - 1U; /* Set the current data size */
  if (RangeCheck(FromAddress, Size) != (LDD_TError)ERR_OK) { /* Is an address range of desired operation out of used flash memory areas? */
    return ERR_PARAM_ADDRESS;          /* If yes, return error. */
  }
  if (((FromAddress & EraseUnitMask) != 0U) || ((Size & EraseUnitMask) != 0U)){ /* Is the desired area misaligned to erasable unit borders? */
    return ERR_PARAM_ADDRESS;          /* If yes, return error. */
  }
  /* Filling of the internal state structure */
  DeviceDataPrv->CurrentOperation = LDD_FLASH_ERASE; /* Set the current operation type */
  DeviceDataPrv->CurrentOperationStatus = LDD_FLASH_START; /* Set the current operation status to START */
  DeviceDataPrv->DataCounter = Size;   /* Reset Data counter */
  DeviceDataPrv->CurrentDataPtr = NULL; /* Reset the "Data pointer" for the operation */
  DeviceDataPrv->CurrentFlashAddress = FromAddress; /* Reset the "From address" for the operation */
  DeviceDataPrv->CurrentDataSize = EraseUnitMask+1; /* Set the current data size */
  DeviceDataPrv->CurrentCommand = LDD_FLASH_ERASE_SECTOR; /* Set the current operation flash command */
  FTFE_PDD_EnableInterrupts(FTFE_BASE_PTR, FTFE_PDD_COMMAND_COMPLETE_INT); /* Enable the Command complete interrupt */
  return ERR_OK;                       /* Return with no error */
}

 

 

если посылаю FC_CMD_ERASE  5000 хоть десять раз - все хорошо FC_CMD_ACK

а если меняю адрес - PE_ISR(Cpu_Interrupt).

 

FC_CMD_ERASE  5000  - FC_CMD_ACK

FC_CMD_ERASE  5000  - FC_CMD_ACK

FC_CMD_ERASE  5000  - FC_CMD_ACK

FC_CMD_ERASE  4000  - FC_CMD_ACK

FC_CMD_ERASE  4000  - PE_ISR(Cpu_Interrupt).

 

а вот скажем первая страница всегда падает на второй раз

 

FC_CMD_ERASE  4000  - FC_CMD_ACK

FC_CMD_ERASE  4000  - PE_ISR(Cpu_Interrupt).

 

Я сгенерировал бинарник бутлодера - 16820 байт.

а между тем

case FC_CMD_QUIT:
{
	SCB_VTOR = RELOCATION_VERTOR_ADDR;
	JumpToUserApplication(RELOCATION_VERTOR_ADDR);
								
}
break;

где RELOCATION_VERTOR_ADDR = 0x04000 (16384 байт)

 

как говорил Киса Воробьянинов - за такое морду бить надо. но их апликаха всё же работает.

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, jenya7 сказал:

но их апликаха всё же работает.

К сожалению, я не знаком с вашим микроконтроллером. Но пару причин я назвать смог. Вам же следует почитать документацию, и проверить соответствие алгоритма этой документации. И написать свой код. Сколько это времени займёт? На чужих примерах кода далеко не уедешь. А если и уедешь, то очень быстро придётся вернуться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

блиииин. вот я лох. оригинальный булодер - 9к. А я свой раздул до 17к. Естественно я затирал часть програмы. Нужно сдвинуть RELOCATION_VERTOR_ADDR = 0x05000.

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

17к для бутлоадера на юарте? А чей код вначале представлен. А то лежат кинетисы и что-то у них с доками ну прям не так как у stm32, на сайте пяток документов и все. Думаю стоит ли их вообще трогать. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 hours ago, MasterElectric said:

17к для бутлоадера на юарте? А чей код вначале представлен. А то лежат кинетисы и что-то у них с доками ну прям не так как у stm32, на сайте пяток документов и все. Думаю стоит ли их вообще трогать. 

я добавил опцию прожига FPGA, отображение на дисплее, ну и всякие фичеры, мало помалу код раздулся почти в два раза. я лично доволен кинетисами, вся периферия работает чётко и есть полезные фичеры которые мы используем, такие как криптография и аппаратный CRC.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 минут назад, jenya7 сказал:

мало помалу код раздулся почти в два раза.

Мой код загрузчика при старте проверяет собственную CRC. В случае несопадения зацикливается. При прошивке проверяет, что адрес приложения находится в разрешенном диапазоне адресов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...