cancel
Showing results for 
Search instead for 
Did you mean: 

PGSERR and PGPERR Problem

DCtech
Associate II

I have a problem with PGSERR and PGPERR bits being set after reset operation

I am using stm32f4 board than I am using CANBUS and FW update process.

When I use serial debug print in MX_CAN1_Init function. I faced with flash erasing error. Then I analyse that error I found PGSERR and PGPERR bits set.

These bits have to be "0" .

I wanted to analyze this problem so I did these test in my initlize states: 

MX_CAN1_Init();
 
 Serialdebugprint("Read PGAERR FLAG %d\n",__HAL_FLASH_GET_FLAG((FLASH_FLAG_PGPERR)));
 
 Serialdebugprint("Read PGSERR FLAG %d\n",__HAL_FLASH_GET_FLAG((FLASH_FLAG_PGSERR)));

I get this value:

Read PGAERR FLAG 64

Read PGSERR FLAG 128

But these flag has to be 0. After the reset.

If I removed the MX_CAN1_Init these flag equals to "0".

When I changed some parameter in the CAN_Init function for example communication speed to 83.3kps to 1Mbs I get this flag as 0 and 128 . By the way when I remove the serialdebug I get the 0 and 128 again.

If I put the MX_CAN1_Init function after a few function than this flag returns "0" .

What is the reason?

/**
 * @brief CAN1 Init function
 * @retval null
 */
 
static void MX_CAN1_Init(void)
{
  CAN_FilterTypeDef  sFilterConfig;
 
  
  hcan1.Instance = CAN1;
  hcan1.Init.Prescaler = 28; //3
  hcan1.Init.Mode = CAN_MODE_NORMAL;
  hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan1.Init.TimeSeg1 = CAN_BS1_15TQ; //11
  hcan1.Init.TimeSeg2 = CAN_BS2_2TQ; //2
  hcan1.Init.TimeTriggeredMode = DISABLE;
  hcan1.Init.AutoBusOff = ENABLE;
  hcan1.Init.AutoWakeUp = DISABLE;
  hcan1.Init.AutoRetransmission = ENABLE;
  hcan1.Init.ReceiveFifoLocked = DISABLE;
  hcan1.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
 
    /*##-2- Configure the CAN Filter ###########################################*/
  sFilterConfig.FilterBank = 0;
  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
  sFilterConfig.FilterIdHigh = 0x0000;
  sFilterConfig.FilterIdLow = 0x0000;
  sFilterConfig.FilterMaskIdHigh = 0x0000;
  sFilterConfig.FilterMaskIdLow = 0x0000;
  sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
  sFilterConfig.FilterActivation = ENABLE;
  sFilterConfig.SlaveStartFilterBank = 0;
 
  if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
  {
    /* Filter configuration Error */
        // SerialPrint("FILTER ERROR !!");
    Error_Handler();
  }
 
  /*##-3- Start the CAN peripheral ###########################################*/
  if (HAL_CAN_Start(&hcan1) != HAL_OK)
  {
    // SerialPrint("CAN START ERROR !!");
    /* Start Error */
    Error_Handler();
  }
 
  /*##-4- Activate CAN RX notification #######################################*/
  if(HAL_CAN_ActivateNotification(&hcan1,CAN_IT_TX_MAILBOX_EMPTY | CAN_IT_RX_FIFO0_MSG_PENDING |CAN_IT_BUSOFF) != HAL_OK)
  {
    Error_Handler();
  }
  Serialdebugprint("Success CAN Init \n");
}

 Serialdebugprint function:

void Serialdebugprint(const char *serial_data, ...)
{
  char uartbuffer[1024]="";
  va_list arg;
  va_start(arg, serial_data);
  uint16_t len = vsnprintf(uartbuffer, 1024, serial_data, arg);
  va_end(arg);
  HAL_UART_Transmit(&huart2, (uint8_t *)uartbuffer, len, 100);
 
}

I think problem start HAL_UART_Transmit(&huart2, (uint8_t *)uartbuffer, len, 100) after this line. What is the reason for ? 

7 REPLIES 7
berendi
Principal

> PGSERR and PGPERR bits set

It usually indicates that there was a write attempt to flash. Check the code for uninitialized pointers and compiler warnings about dropping the const qualifier.

I added some spesific details in my issue.

DCtech
Associate II

Is there any another answer for this problem? I gave initlize value all the paramater. And I add some details on my question @berendi​ 

DCtech
Associate II

I found some problem detail with debug operation. In the UART_Transmit function, If I check the flash flags after the

if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) and

huart->Instance->DR = (*pData++ & (uint8_t)0xFF); this lines than I get flash registers set.

berendi
Principal

This looks like a stack/heap overflow issue. Some toolchain (Keil or IAR I can't recall it now) is known to allocate too little space for stack+heap by default, the startup file for gcc gives all unused RAM to stack and heap, but it can be still tight if the program uses lots of variables.

Serialdebugprint() uses a (for embedded systems) huge amount of stack storage, *printf and its friends allocate some buffers on heap. Set a breakpoint on the line that calls HAL_UART_Transmit(), then examine the stack pointer register. Check the .map file for any overlap with program variables.

Increase the space available to stack and heap all the way you can, or rather find a way to get rid of those temporary buffers. Tip: override the _write() function to write to the serial port, then you can use printf() directly in your code.

DCtech
Associate II

@berendi I am not using Keil or IAR . Makefile generated by CubeMx. So how can I determine the stack/heap overflow ? I dont have any .map file .

berendi
Principal

Find out the value of the stack pointer either by the method above, or

void *stack = (void *)__get_MSP();

and the top of the heap

void * heap = sbrk(0);

do both between the calls to vsnprintf() and HAL_UART_Transmit().

If stack < heap then you have a problem.