Skip to main content
DCtech
Associate III
July 23, 2020
Question

PGSERR and PGPERR Problem

  • July 23, 2020
  • 7 replies
  • 1761 views

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 ? 

    This topic has been closed for replies.

    7 replies

    berendi
    Principal
    July 24, 2020

    > 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.

    DCtech
    DCtechAuthor
    Associate III
    July 24, 2020

    I added some spesific details in my issue.

    DCtech
    DCtechAuthor
    Associate III
    July 27, 2020

    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
    DCtechAuthor
    Associate III
    July 27, 2020

    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
    July 27, 2020

    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
    DCtechAuthor
    Associate III
    July 28, 2020

    @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
    July 28, 2020

    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.