cancel
Showing results for 
Search instead for 
Did you mean: 

Hard Fault on the first or the second snmpwalk request to SNMP agent

AJOLY.2
Associate II

EDITED on 01/07/2021. I still have a Hard Fault but I have updated my code and added details.

Hello,

I am currently trying to set-up a SNMP agent on a STM32756G-EVAL2 board (with STM32F756NGHx proc). I am using STM32CubeIDE for generation, for writing code and to flash and debug the binary on the target.

My current goal is to make a functional SNMP agent capable of answering GET request from a SNMP master (using Net-SNMP tools like snmpwalk and snmpget). Aside from having a MIB II, I want to add just one or two private/enterprise OID node giving elapsed time and/or temperature (on read-only mode). I use FreeRTOS and Netconn API (it is not working with RAW API as there are some mutexes/semaphores blocking communications).

I have managed to build the MIB II and a private MIB containing one node giving elapsed time (from ticks). Here is the code :

...
 
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
  .name = "defaultTask",
  .priority = (osPriority_t) osPriorityNormal,
  .stack_size = 2048 * 4
};
 
...
 
static s16_t sensor_ds1682_get_value(struct snmp_node_instance* instance, void* value);
PUTCHAR_PROTOTYPE;
 
/* sensor_ds1682 .1.3.6.1.4.1.XXXXX.1.1 */
static const struct snmp_scalar_node sensor_ds1682 = SNMP_SCALAR_CREATE_NODE_READONLY(
  1, SNMP_ASN1_TYPE_INTEGER, sensor_ds1682_get_value);
/* xxxxx .1.3.6.1.4.1.XXXXX.1 */
static const struct snmp_node* const xxxxx_nodes[] = {
  &sensor_ds1682.node.node
};
static const struct snmp_tree_node xxxxx_node = SNMP_CREATE_TREE_NODE(1, xxxxx_nodes);
static const u32_t prvmib_base_oid[] = {1, 3, 6, 1, 4, 1, XXXXX, 1};
const struct snmp_mib mib_private = SNMP_MIB_CREATE(prvmib_base_oid, &xxxxx_node.node);
 
int main(void)
{
  HAL_Init();
 
  SystemClock_Config();
 
  MX_GPIO_Init();
  MX_USART1_UART_Init();
 
  osKernelInitialize();
 
  defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
 
  osKernelStart();
 
  while (1)
  {
 
  }
}
 
...
 
static s16_t sensor_ds1682_get_value(struct snmp_node_instance * instance, void * value)
{
  u32_t res = (u32_t) (osKernelGetTickCount() / 1000);
 
  u32_t * uint_ptr = (u32_t *) value;
 
  *uint_ptr = (u32_t)res;
  return sizeof(*uint_ptr);
}
 
void StartDefaultTask(void *argument)
{
  /* init code for LWIP */
  MX_LWIP_Init();
  /* USER CODE BEGIN 5 */
 
  snmp_threadsync_init(&snmp_mib2_lwip_locks, snmp_mib2_lwip_synchronizer);
 
  ip_addr_t dstaddr;
  IP4_ADDR(&dstaddr, 192, 168, 0, 2);
 
  snmp_mib2_set_syscontact_readonly((const u8_t *) "Contact XXXXX", NULL);
  snmp_mib2_set_syslocation_readonly((const u8_t *) "Location XXXXX", NULL);
  snmp_set_auth_traps_enabled(DISABLE);
  snmp_mib2_set_sysdescr((const u8_t *) "Description XXXXX", NULL);
  snmp_mib2_set_sysname_readonly((const u8_t *) "Name XXXXX", NULL);
 
  const struct snmp_obj_id device_enterprise_oid = {7, {1, 3, 6, 1, 4, 1, XXXXX}};
  snmp_set_device_enterprise_oid(&device_enterprise_oid);
 
  snmp_trap_dst_ip_set(0, &dstaddr);
  snmp_trap_dst_enable(0, 0);
 
  static const struct snmp_mib *my_snmp_mibs[] = {
    &mib2,
    &mib_private
  };
  snmp_set_mibs(my_snmp_mibs, LWIP_ARRAYSIZE(my_snmp_mibs));
 
  snmp_init();
 
  /* Infinite loop */
  for(;;)
  {
    osDelay(10);
  }
  /* USER CODE END 5 */
}

Here are few commands and the output from my terminals:

bash-4.2$ /opt/snmp/bin/snmpwalk -Of -c public -v 1 192.168.0.10 .1.3.6.1.4.1.XXXXX.1.1.0
Timeout: No Response from 192.168.0.10

The main problem here is that my program usually makes snmpwalk timeout at the first or the second command, and I get a Hard Fault during debugging on STM32CubeIDE. Before the update, I was able to get a result or two with GET or GET NEXT snmp resquest but with the adding of debug options in lwipopts.h (via STM32CubeMX generation), I'm with getting the Hard Fault sooner and before my program can enter the Netconn send services.

With some debugging, I track the flow from the HAL_ETH_IRQHandler function to the idle task function portTASK_FUNCTION where prvCheckTasksWaitingTermination is called. The a task resumes and it goes in low_level_input, ethernetif_input, tcpip_input then tcpip_inpkt.

In this function tcpip_inpkt, this line is executed:

msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT);

and it makes the program Hard Fault. From there, I run out of ideas, mostly because i'm quite new to the embedded software world. I'll try to explore the memp_malloc function but It would probably be a rough experience for a beginner to debug.

Thanks for reading, any help is welcomed!

Have a nice day.

2 REPLIES 2
AJOLY.2
Associate II

First post updated with a new code and updated details of the problem and my debugging. I cannot still understand what triggers the Hard Fault.

AJOLY.2
Associate II

Hello again,

I actually resolved my problem. First, I completely reset my lwIP configuration in the .ioc file. Then the only thing I changed was to double the lwIP MEM_SIZE and SNMP_STACK_SIZE and I also increased the FreeRTOS TOTAL_HEAP_SIZE from 15XXX to 30XXX Bytes.