Announcement

Collapse
No announcement yet.

Dealing with reception buffer and sleeping

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Dealing with reception buffer and sleeping

    My modules pass time in sleep and wake up period constantly. On a applicative event, one of my modules wake up and transmit a time related information. The problem happen when one of the receiving module wake up, he process a old frame with an old information of time.

    As I see, the SNAP kernel process is stop when passing in sleep with a reception message queue filled. At wake up the process is completed and i have to deal with a old message. At this time i can't know if the message is correct or just a old.

    There is some mechanisms to use for the reception process like the use of RPC_SENT hook with getInfo(9) for the transmission? I'm try to ensure that there's no frame saved in queue before going to sleep. It's possible to have acces at the information of the reception queue to avoid this problem?

    I'm running on the firmware : RF200_AES128_debug_SnapV2.4.22.sfi

  • #2
    MakL - yes indeed you have got the mechanism (HOOK_RPCSENT) that allows you to know when it is clear to sleep.

    The sleep() function is one of the built-in procedures in SNAP that is executed immediately (See SNAP Reference Manual for a complete list of immediate/blocking/non-blocking functions). This means you could have an outstanding PRC or UART data that is enqueued to be sent, but has not yet been transmitted.

    The HOOK_RPC_SENT and HOOK_STDOUT event handlers are designed to tell you when these packets have been transmitted and you are good to either enqueue another to be sent, restart the system, or to execute something like sleep.

    The getInfo(9) call will allow you to track exactly which RPC was sent.
    sigpic
    Proven Solutions for the Internet of Things
    www.synapse-wireless.com

    Comment


    • #3
      More details on the problem with the receive buffer

      What I see is the treatement of a message, received before the sleep period and process after when the module wake up.

      The problem is sporadic but happen on a constant base.

      This script is use to show the use of RPC Hook for the transmission process and to show the treatement of getInfo(9) at each rpc call. The information content in getInfo(9) is also use before sleep to ensure to not wake up with
      a old message, but this technique doesn't seem to work. There anything to do to avoid this problem.

      Code:
      """
      Test script    
      """
      
      # Use Synapse Evaluation Board definitions
      from synapse.evalBase import *
      
      # Globals
      WAKE_PERIOD = 100       # Wake up period [1ms]
      
      # Identify RPC ID to track
      RPC_SENT_Type = 0
      
      RPC_TYPE_MESSAGE  = 1  # Track RPC ID for a message call
      RPC_TYPE_RESPONSE = 2  # Track RPC ID for a response call
      
      valueRpcId = 0 
      
      # RPC ID tracker
      RPC_Packet_Buffer_OLD = 0 # RPC ID save before sleep
      RPC_Packet_Buffer_NEW = 0 # RPC ID after sleep
      
      # RPC SEND flags
      ReadyToSend     = True    # Message flag  to ensure transmission, if false the message processing ins't done
      ReadyToResponse = True    # Response flag to ensure transmission, if false the message processing ins't done
      
      # Rolling timer, 1 ms Tick for time related information in the message 
      timeCount     = 0
      
      # Wake up period count(Only for the receiving node)
      wakeTimer     = 0    
      
      # Number of message to send, decremential count
      messageCount  = 0        
      
      # Go to sleep flag, if True the wakeTimer decount in completed
      goToSleep   = False 
        
      # First pass in message command, launch wake/sleep period for the receiving node
      firstPass = False
      
      # Hard-coded address for Portal (only for debug purposes)
      portalAddr = '\x00\x00\x01'   
      
      @setHook(HOOK_STARTUP)
      def startupEvent():
          """This is hooked into the HOOK_STARTUP event"""
          
          # intialize the proto board 
          initProtoHw() 
          
          # Module is wakeUp 
          lightLed()
      
      @setHook(HOOK_1MS)
      def Sys_DoEvery1ms(tick):
          """
          Hooked into the HOOK_1MS event. Called every 1ms
          """
          global messageCount
          global valueRpcId    
          global ReadyToSend
          global ReadyToResponse    
          global RPC_SENT_Type        
          global timeCount
          global wakeTimer
          global goToSleep
          
          # Increment rolling counter for the time related information
          if timeCount != 10000:
              timeCount += 1
          else:
              timeCount = 0
          
          # Send message
          if ReadyToSend is True:
              if messageCount != 0:
                  messageCount -= 1 
                          
                  # Waiting treatement of module 
                  ReadyToSend = False
                  
                  # Send time related information
                  mcastRpc(1,1,"Message",timeCount)
                  RPC_SENT_Type = RPC_TYPE_MESSAGE
                  
                  # Manage Rpc ID
                  valueRpcId = getInfo(9)  
          
          # Keep track of wake time(Only for the receiving node)
          if wakeTimer != 0:
              wakeTimer -= 1
              if (wakeTimer == 0):
                  goToSleep = True 
          
          # Manage sleep process (Only for the receiving node)
          if (goToSleep is True) and (ReadyToResponse is True):
              goToSleep = False
              GoSleep()  
         
      
      @setHook(HOOK_RPC_SENT)   
      def Sys_RpcSentEvent(rpcID):
          
          global valueRpcId    
          global ReadyToSend
          global ReadyToResponse    
          global RPC_SENT_Type
          global RPC_Packet_Buffer_OLD
          
          # Is message send ?
          if RPC_SENT_Type == RPC_TYPE_MESSAGE:
              if rpcID == valueRpcId:
                  # Message have been send
                  ReadyToSend = True   
          
          # Is response send ?
          if RPC_SENT_Type == RPC_TYPE_RESPONSE:
              if rpcID == valueRpcId:
                  # Response have been send
                  ReadyToResponse = True
                  
                  # Get packet buffer tag before sleep
                  RPC_Packet_Buffer_OLD = getInfo(9)  
        
          
      def Message(Time):
          """ 
          For the first call of this function the wake/Sleep sequence will be launch.
          The information of time is send back.
          """ 
          global ReadyToResponse    
          global wakeTimer 
          global valueRpcId    
          global RPC_SENT_Type    
          global firstPass 
          
          # Response with the receive time value
          mcastRpc(1,1,"Response",Time)
          RPC_SENT_Type = RPC_TYPE_RESPONSE
          
          # Manage Rpc ID
          valueRpcId = getInfo(9) 
              
          # Response have been send
          ReadyToResponse = False 
      
          
          # Start sleep process
          if firstPass is False:        
              firstPass = True        
              # Start wake/sleep sequence for the receiving node
              wakeTimer = WAKE_PERIOD  
      
      def Response(Time):
          """ No treatement for the initiator of the exchange  """
          pass
      
      def StartMessage():   
          """ 
          To start transmit 30 RPC in sequence. Each RPC are send after 
          each other after checking the rpcID in the RPC Hook
          """ 
          global messageCount # Decounting number of message 
          global ReadyToSend  # Message flag to ensure transmission
       
          messageCount = 30  
          ReadyToSend  = True
      
      
      def GoSleep():
          """ 
          When all know message have been transmitted, ensure by the RPC ID
          the node will go to sleep. The RPC ID before sleep and after are 
          then compare.
          """        
          global RPC_Packet_Buffer_OLD
          global RPC_Packet_Buffer_NEW 
          global wakeTimer
          global firstPass 
          
          # Get packet buffer tag before sleep
          #RPC_Packet_Buffer_OLD = getInfo(9)
              
          # Inform of sleep period
          ledsOff()
      
          # Sleep period 2s
          sleep(1,2)    
          
          # Inform of wakeUp period
          lightLed()
          
          # Get packet buffer tag after sleep
          RPC_Packet_Buffer_NEW = getInfo(9)
          
          # Compare RPC ID
          if RPC_Packet_Buffer_OLD != RPC_Packet_Buffer_NEW:
              eventString = "RPC NOT match"
              rpc(portalAddr, "logEvent", eventString)
          else:
              eventString = "RPC match"
              rpc(portalAddr, "logEvent", eventString)
       
          # To reproduce a wake/sleep sequence again
          firstPass = False

      Comment

      X