How can i set a timer in my project?

Hello everyone,

I want to be able to set a timer in my project. With this timer i want to be able to make my current comsumption evaluation easier.

I am using the nrf9160 DK.

I proceeded the following way:

#include <zephyr.h>
#include <stdio.h>
#include <nrf9160.h>
#include <device.h>

#define TIMER_INTERVAL_SEC 1

struct k_timer my_timer;

void my_expiry_function(struct k_timer *timer_id){};


void main(void){

        k_timer_init(&my_timer, my_expiry_function, NULL);
        k_timer_start(&my_timer, K_SECONDS(TIMER_INTERVAL_SEC), K_SECONDS(TIMER_INTERVAL_SEC));
        
}

unfortunately it is not working, can someone please help me resolve this issue?

Best regards,

Cedric

  • I tested your sample and was able to make it work

    • Extract the following project to ncs

    simple_timer.zip

    • Build it with the board nrf9160dk_nrf9160_ns
    • Open a serial terminal and you will see the following output:

    .
    .
    .
    .
    26 NRF_I2S              Non-Secure	OK
    27 NRF_GPIOTE1          Non-Secure	OK
    
    SPM: NS image at 0x10000
    SPM: NS MSP at 0x200159a0
    SPM: NS reset vector at 0x12379
    SPM: prepare to jump to Non-Secure image.
    *** Booting Zephyr OS build v2.6.99-ncs1  ***
    [00:00:00.205,627] [1B][0m<inf> asset_tracker: Timer sample started[1B][0m
    [00:00:01.205,688] [1B][0m<inf> asset_tracker: Expiry function is running[1B][0m
    [00:00:02.205,718] [1B][0m<inf> asset_tracker: Expiry function is running[1B][0m
    [00:00:03.205,688] [1B][0m<inf> asset_tracker: Expiry function is running[1B][0m
    [00:00:04.205,749] [1B][0m<inf> asset_tracker: Expiry function is running[1B][0m
    [00:00:05.205,688] [1B][0m<inf> asset_tracker: Expiry function is running[1B][0m
    [00:00:06.205,718] [1B][0m<inf> asset_tracker: Expiry function is running[1B][0m
    [00:00:07.205,688] [1B][0m<inf> asset_tracker: Expiry function is running[1B][0m

    Best regards,

    Simon

  • Hi @Simon,

    Thanks your very much.

    BR,

    Cedric

  • Hi simon,

    using the timer while evaluating the current consumption of the board, couldn't trace the timer actually working when looking at the Graph

    Here is my code:

    /*
     * Copyright (c) 2020 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    #include <zephyr.h>
    #include <stdio.h>
    #include <modem/lte_lc.h>
    #include <net/socket.h>
    #include <random/rand32.h>
    #include <net/coap.h>
    
    #include <modem/nrf_modem_lib.h>
    #include <logging/log.h>
    #include <sys/printk.h>
    #include <modem/modem_key_mgmt.h>
    #include <net/tls_credentials.h>
    
    
    #include <nrf9160.h>
    #include <device.h>
    #include <drivers/gpio.h>
    
    #include <nrfx.h>
    
    #include <cJSON.h>
    #include <cJSON_os.h>
    
    
    #include "ui.h"
    #include "config.h"
    
    /* 1000 msec = 1 sec */
    //#define SLEEP_TIME_MS 100
    #define TIMER_INTERVAL_MSEC 500
    #define LOG_LEVEL 3
    
    LOG_MODULE_REGISTER(asset_tracker, LOG_LEVEL);
    
    #define PAYLOAD_BYTES 100
    #define APP_COAP_VERSION 1  // CoAP Version
    
    struct k_timer my_timer;
    struct device *dev;
    // uint8_t toggle = 0;
    
    static int sock; // BSD socket API
    static struct sockaddr_storage server; // structure für CoAP-Server- Addressinformation.
    
    
    static uint16_t next_token; // request ID
    static struct pollfd fds; // File descriptor
    
    static uint8_t data[PAYLOAD_BYTES]; // CONFIG_DATA_UPLOAD_SIZE_BYTES Maximale Nachrichtgröße
    
    
    void my_expiry_function(struct k_timer *timer_id){
        printk("Expiry function is running\n");
    }
    
    void timer(void){
    
            printk("Timer started\n");
            k_timer_init(&my_timer, my_expiry_function, NULL);
            k_timer_start(&my_timer, K_MSEC(TIMER_INTERVAL_MSEC), K_MSEC(TIMER_INTERVAL_MSEC));
            //k_timer_stop(&my_timer);
    }
    
    /*************************************************************************************************************/
    
    // Benutzeroberflächenmodul.
    static void ui_evt_handler(struct ui_evt *evt) // Event-Handler für LEDS
    {
    	if (!evt) {
    		return;
    	}
    }
    
    /*************************************************************************************************************/
    
    cJSON * createJsonFromParams(void)
    {
    	
    	char *value = "50";
            char *number = "12";
            cJSON *root;
    
            /* JSN-Objekt erstellen */
    	root = cJSON_CreateObject();
    
            /* Payload hinzufügen */
    	cJSON_AddItemToObject(root, "JSON", cJSON_CreateString(value));
    	cJSON_AddItemToObject(root, "Content-Form", cJSON_CreateString(number)); 
    
       return root;
    
    }
    
    /*************************************************************************************************************/
    
    static int dtls_init(void){
    
    int err;
    
    #if defined(CONFIG_NRF_MODEM_LIB) && defined(CONFIG_MODEM_KEY_MGMT)
    	err = modem_key_mgmt_write(CONFIG_COAP_SEC_TAG,
    				MODEM_KEY_MGMT_CRED_TYPE_PSK,
    				client_psk,
    				strlen(client_psk));
    	if (err < 0) {
    		printk("Bereitstellung des PSK fehlgeschlagen: %d", err);
                    return err;
    	}
    
           err = modem_key_mgmt_write(CONFIG_COAP_SEC_TAG,
    				MODEM_KEY_MGMT_CRED_TYPE_IDENTITY,
    				psk_id,
    				strlen(psk_id));
    	if (err < 0) {
    		printk("Bereitstellung der PSK-ID fehlgeschlagen: %d", err);
                    return err;
    	}
    
    #endif
    
    
    #if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
    
            // Registrierung des Client PSKs.
    	err = tls_credential_add(CONFIG_COAP_SEC_TAG,
    				TLS_CREDENTIAL_PSK,
    				client_psk,
    				sizeof(client_psk));
    	if (err < 0) {
    		printk("Fehler beim Registrieren von PSK: %d", err);
                    return err;
    	}
    
            // Registrierung der Client Identität.
    	err = tls_credential_add(CONFIG_COAP_SEC_TAG,
    				TLS_CREDENTIAL_PSK_ID,
    				psk_id,
    				sizeof(psk_id));
    	if (err < 0) {
    		printk("Fehler beim Registrieren von PSK ID: %d", err);
                    return err;
    	}
    
    #endif
           
            return 0;
    
            timer();
            
    
    }
    
    /*************************************************************************************************************/
    
    static int server_initialisieren(void)
    {
    
    	int err;
    	struct addrinfo *result;
    	struct addrinfo hints = {
    		.ai_family = AF_INET,
    		.ai_socktype = SOCK_DGRAM
    	};
    	
            char ipv4_addr[NET_IPV4_ADDR_LEN];
    
    	err = getaddrinfo(CONFIG_SERVER_ADDRESS, NULL, &hints, &result);
    	if (err != 0) {
    		printk("ERROR: getaddrinfo fehlgeschlagen %d\n", err);
    		return -EIO;
    	}
    
    	if (result == NULL) {
    		printk("ERROR: Adresse nicht gefunden\n");
    		return -ENOENT;
    	}
    
    	/* IPv4 Address. */
    	struct sockaddr_in *server4 = ((struct sockaddr_in *)&server);  // Socket-Adressstruktur für IPv4
    
    	server4->sin_addr.s_addr =
    		((struct sockaddr_in *)result->ai_addr)->sin_addr.s_addr;
    	server4->sin_family = AF_INET;  // AF_INET  = IP Protokoll Version 4 (IPv4)
    	server4->sin_port = htons(CONFIG_SERVER_PORT);  //Schreibe Port in Netzwerk-Byte-Order in das Feld sin_port
    
    	inet_ntop(AF_INET, &server4->sin_addr.s_addr, ipv4_addr,
    		  sizeof(ipv4_addr));  // Schreibe IP-Adresse des Servers in die sockaddr_in-Struktur
    
    
    	printk("IPv4 Adresse des Servers: %s\n", ipv4_addr);
    
    
    	/* Free the address. */
            freeaddrinfo(result);
    
    	return 0;
    
            timer();
            
    }
    
    /*************************************************************************************************************/
    
    static int server_verbinden(void)
    {
    	int err;
    
    #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) && defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
    
    	sec_tag_t tls_tag_list[] = {
    		CONFIG_COAP_SEC_TAG,
    	};
    
    	sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_DTLS_1_2);
    	if (sock < 0) {
    		printk("Fehler beim Erstellen des CoAP/DTLS-Sockets: error %d\n", errno);
                    err = -errno;
    		goto error;
    	}
    
    	err = setsockopt(sock, SOL_TLS, TLS_SEC_TAG_LIST,
    			 tls_tag_list, sizeof(tls_tag_list)); // Socket-Sicherheits-Tag einrichten
    	if (err < 0) {
    		printk("ERROR: TLS_SEC_TAG_LIST option: %d\n", errno);
                    err = -errno;
    		goto error;
    	}
            
    #else
    	sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    	if (sock < 0) {
    		printk("Fehler beim Erstellen des CoAP-Sockets: error %d\n", errno);
                    err = -errno;
    		goto error;
    	}
    #endif
    
            ui_led_set_pattern(UI_CLOUD_CONNECTING); // Led 4 blinkt zum Signalisieren der Verbindungsherstellung zum Server
    
    	err = connect(sock, (struct sockaddr *)&server,
    		      sizeof(struct sockaddr_in)); // Verbindung zum Server herstellen
    
            // err=0 => success, err<0 => fehler
    	if (err < 0) {
    		printk("Verbindung fehlgeschlagen: error %d\n", errno);
                    err = -errno;
    		goto error;
    	}
    
            ui_led_set_pattern(UI_CLOUD_CONNECTED);  // Led 4 leuchtet zum Signalisieren der Verbindung zum Server 
    
            /* Initialize FDS, for poll. */
    	fds.fd = sock;
    	fds.events = POLLIN;
    
    	/* Randomize token. */
    	next_token = sys_rand32_get();
    
    	return 0;
            
            timer();
            
    
    error:
    	(void)close(sock); // beende die Verbindung zum Socket 
    
    	return err;
    }
    
    /*************************************************************************************************************/
    
    //int coap_ping(void)
    //{
    //	int err;
    //	struct coap_packet ping;
    
    //	next_token = 0;
    
    //	err = coap_packet_init(&ping, data, sizeof(data),
    //			       APP_COAP_VERSION, COAP_TYPE_CON,
    //			       0, NULL, 0, coap_next_id());
    //	if (err < 0) {
    //		printk("Failed to create CoAP request, %d\n", err);
    //		return err;
    //	}
    
    //	err = send(sock, ping.data, ping.offset, 0);
    //	if (err < 0) {
    //		printk("Failed to send CoAP PING, %d\n", errno);
    //		return -errno;
    //	}
    
    //	printk("CoAP PING sent: token 0x%04x\n", next_token);
    
    //	return 0;
    //}
    
    /*************************************************************************************************************/
    
    static int uebertragung_zu_server_fn(void)
    {
    	int err;
    
            struct coap_packet request; // Anfragepaket
    
            cJSON *root = createJsonFromParams();  /* Gibt Payload an */
    
          
    	char *payload = cJSON_Print(root);
    	if (payload == NULL) {
    		printk("ERROR print...\n");
    	}
    
            printk("Payload von %d bytes wird an den Californium Server zugeschickt\n", strlen(payload));
           
            next_token++;
    
            // Initialisiere CoAP Anfrage
            err = coap_packet_init(&request, data, sizeof(data),
    			       APP_COAP_VERSION, COAP_TYPE_NON_CON,
    			       sizeof(next_token),(uint8_t *)&next_token,
                                   COAP_METHOD_PUT, coap_next_id());
    
    	if (err < 0) {
    		printk("CoAP-Anfrage konnte nicht erstellt werden, error %d\n", err);
    		return err;
    	}
    
            // Fügt eine Option URI-path an das Paket an
    	coap_packet_append_option(&request, COAP_OPTION_URI_PATH,
                                      (uint8_t *)CONFIG_COAP_RESOURCE, 
                                      strlen(CONFIG_COAP_RESOURCE));
    
           // Fügt eine content-format-option with the value JSON an das Paket an
            coap_append_option_int(&request,
                                    COAP_OPTION_CONTENT_FORMAT,
                                      COAP_CONTENT_FORMAT_APP_JSON);
    
            // Payload-Marker an CoAP-Paket anhängen
            coap_packet_append_payload_marker(&request);
    
            // Payload an CoAP-Paket anhängen
            err=coap_packet_append_payload(&request, (uint8_t *)payload, strlen(payload));
            if (err < 0) {
    		printk("Payload konnte nicht angehängt werden, %d\n", err);
    		return err;
    	}           
            
            free(payload);
    
    	/* free all objects under root and root itself */
            cJSON_Delete(root);
    
    	err = send(sock, request.data, request.offset, 0); // Daten werden an den Port 5684 gesendet
    	if (err < 0) {
    		printk("Paket konnte nicht übertragen werden,error %d\n", errno);
    		return -errno;
    	}
    
            printk("CoAP Anfrage gesendet: token 0x%04x\n", next_token);
    
            return 0;
    
            timer();
            
    
    }
    
    /*************************************************************************************************************/
    
    // Ein Semaphore ist ein Kernel-Objekt, das ein traditionelles Zählsemaphor implementiert.
    // Ein Semaphor wird verwendet, um den Zugriff auf eine Reihe von Ressourcen durch mehrere
    // Threads zu steuern und um die Verarbeitung zwischen einem produzierenden und einem 
    // verbrauchenden Thread oder Interrupt Service Routine (ISRs) zu synchronisieren.
    
    static K_SEM_DEFINE(lte_verbunden, 0, 1); // Semaphore statisch definiert und initialisiert. 
                                              // lte_verbunden = Name des Semaphores. 0 = anfängliche Semaphorezählung 
                                              // 1 = maximal zulässige Semaphoranzahl.
    
    static void lte_handler(const struct lte_lc_evt *const evt)
    {
    	switch (evt->type) {
    	case LTE_LC_EVT_NW_REG_STATUS: // emfangenes Ereignis mit Informationen zum Netwerkregistrierungsstatus
                                           // des Modems
    		if ((evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_HOME) &&
    		     (evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_ROAMING)) {
    			break;
    		}
                      
    		printk("Netwerkregistrierungsstatus: %s",
    			evt->nw_reg_status == LTE_LC_NW_REG_REGISTERED_HOME ?
    			"verbunden mit Heimnetwerk\n" : "verbunden mit Roaming\n");
    
    		k_sem_give(&lte_verbunden); // Gib ein Semaphor an. Setzte die Zählung von lte_verbunden auf Null 
                                                // &lte_verbunden= Adresse des Semapores
    
                    timer();
                    
                      
                    break;                      
    
    
    	case LTE_LC_EVT_PSM_UPDATE: // empfangenes Ereignis mit Informationen zu PSM-Updates. Die Updates enthalten 
                                        //  PSM-Parameter, die vom Netwerk vorgeben wurden.
    
                    // Das zugehörige Payload ist das Mitglied psm_cfg vom Typ lte_lc_psm_cfg in dem Library lte.lc.h
                    // tau = Periodisches Aktualisierungsintervall des Tracking-Bereichs.
                    // active_time = Aktiv-Zeit (Zeit von RRC Leerlauf bis PSM)
    		printk("PSM-Parameter update: TAU: %d, Active time: %d\n",
    			evt->psm_cfg.tau, evt->psm_cfg.active_time);
    		break;
    
    	case LTE_LC_EVT_EDRX_UPDATE:{// empfangenes Ereignis mit Informationen zu eDRX-Updates. Die Updates enthalten 
                                        //  eDRX-Parameter, die vom Netwerk vorgeben wurden.
    
                    // Das zugehörige Payload ist das Mitglied edrx_cfg vom Typ lte_lc_edrx_cfg in dem Library lte.lc.h
                    // edrx = eDRX-Intervallwert [s]
                    // ptw = Paging-Zeitfenster [s]
    		char log_buf[60];
    		ssize_t len;
    
    		len = snprintf(log_buf, sizeof(log_buf),
    			       "eDRX parameter update: eDRX: %f, PTW: %f\n",
    			       evt->edrx_cfg.edrx, evt->edrx_cfg.ptw);
    		if (len > 0) {
    			printk("%s\n", log_buf);
    		}
    		break;
             }
    
    	case LTE_LC_EVT_RRC_UPDATE: // empfangenes Ereignis mit Informationen über den 
                                        // Radio Ressource Control(RRC)-Status des Modems
                    
                    // Das zugehörige Payload ist das Mitglied rrc_mode vom Typ lte_lc_rrc_mode in dem Library lte.lc.h
                    // RRC Modus ist entweder verbunden oder idle.
    		printk("RRC Modus: %s",
    			evt->rrc_mode == LTE_LC_RRC_MODE_CONNECTED ?
    			"verbunden\n" : "Idle\n");
                   
                    timer();
                    
    
    		break;
    
    	case LTE_LC_EVT_CELL_UPDATE: // empfangenes Ereignis mit Informationen über die aktuell verbundene Zelle
    
                    // Das zugehörige Payload ist das Mitglied Cell vom Typ lte_lc_cell in dem Library lte.lc.h
                    // id = Mobilfunkzellenidentifikation
                    // tac = Tracking area code
    		printk("LTE veränderte Zelle: Zelle ID: %d, Tracking area: %d\n",
    			evt->cell.id, evt->cell.tac);
    		break;
    
    	case LTE_LC_EVT_LTE_MODE_UPDATE: // Wenn ein Systemmodus konfiguiert ist,der entweder LTE-M oder NB-IoT
                                             // aktiviert, kann das Modem den aktuell aktiven LTE-Modus basierend auf
                                             // der Netwerkverfügbarkeit ändern. Dieses Ereignis zeigt dann an, welcher
                                             // LTE-Modus derzeit vom Modem verwendet wird.
    
    		printk("Active LTE Modus: %s",
    			evt->lte_mode == LTE_LC_LTE_MODE_NONE ? "None\n" :
    			evt->lte_mode == LTE_LC_LTE_MODE_LTEM ? "LTE-M\n" :
    			evt->lte_mode == LTE_LC_LTE_MODE_NBIOT ? "NB-IoT\n" :
    			"Unknown\n");
    
                    timer();
                    
    
    		break;
    	default:
    		break;
    	}
    }
    
    /*************************************************************************************************************/
    
    static void modem_konfigurieren(void)
    {
    #if defined(CONFIG_NRF_MODEM_LIB) // CONFIG_NRF_MODEM_LIB = verwende Nordic Modem Library
    	if (IS_ENABLED(CONFIG_LTE_AUTO_INIT_AND_CONNECT)) { 
                      // CONFIG_LTE_AUTO_INIT_AND_CONNECT = automatische Registrierung bei LTE-M oder NB-IoT
    		  // passiert nichts, falls der Modem bereits konfiguriert und LTE verbunden ist.
    
    	} else {
    
    		int err; // integer für errors
    
    #if defined(CONFIG_PSM_ENABLE) // CONFIG_PSM_ENABLE fordert PSM vom Modbilfunknetz an.
    
    		/* Das Anfordern von PSM vor der Verbindung ermöglicht es dem Modem, das
    		 * Netwerk bereits während des Verbindungsvorgangs über unseren Wunsch
    		 * nach einer bestimmten PSM-Konfiguration zu informieren, anstatt in 
    		 * einer separaten Anfrage nach der Verbindungsherstellung, die in einigen
    		 * Netzwerken abgelehnt werden kann */
    		
    		err = lte_lc_psm_req(true); // Anfordern des Modems, das Power saving mode zu aktivieren
    		if (err < 0) {
                             // Falls err= negativ =>  Fehler aufgetreten
    
    			printk("Power Saving Mode wurde nicht aktiviert, error: %d\n",
    				err);
    		} else{
                          // falls err=0  => das Anfordern war erfolgreich
    
                          printk("PSM-Modus aktiviert\n\n");
                    }
    #endif
    
    #if defined(CONFIG_EDRX_ENABLE) // CONFIG_EDRX_ENABLE fordert eDRX vom Modbilfunknetz an.
    
    	/** Extended Discontinuous Reception (eDRX) ermöglicht es das Sleep mode
                in RRC idle mode auf Minuten oder Stunden zu verlängern, was noch deutlichere
                Einsparungen beim Energieverbrauch bietet*/
    
    	err = lte_lc_edrx_req(true); // eDRX wird aktiviert
    	if (err<0) {
    		printk("eDRX wurde nicht aktiviert, error: %d\n", err);
    	}else {
    		printk("eDRX aktiviert\n");
    	}
    #endif
    
    
                    ui_led_set_pattern(UI_LTE_CONNECTING); // LED3 blinkt, um der Verbindungsherstellungsvorgang 
                                                          // zu signalisieren.
    		printk("Verbindung zum LTE-Netz wird hergestellt\n");
    		printk("Das kann ein paar Minuten dauern..\n");
    		
                    // lte_lc_init_and_connect_async initialisiert das LTE-Modul, 
                    // konfiguriert das Modem und verbindet sich mit dem LTE-Netzwerk.
                    // lte_lc_init_and_connect_async überprüft zusätzlich die LTE-Ereignisse
                    // vom Typ LTE_LC_EVT_NW_REG_STATUS in lte_handler(), um festzustellen, wann
                    // die LTE-Verbindung besteht.
    
    		err = lte_lc_init_and_connect_async(lte_handler);
    		if (err) {
                    // err= negativ => Fehler aufgetreten
    
    			printk("Modem konnte nicht konfiguriert werden, error: %d\n",
    				err);
    			return;
    		}
                    // err=0 => besteht LTE-Verbindung 
    
                    printk("Mit LTE-Netz verbunden\n");
    		ui_led_set_pattern(UI_LTE_CONNECTED); // LED3 leuchtet, um das Bestehen der Verbindung vorzugeben.
    
                    timer();
                    
    
    	}
    #endif
    }
    
    /*************************************************************************************************************/
    /* Gibt 0 zurück, wenn Daten verfügbar sind.
     * Gibt -EAGAIN zurück, wenn eine Zeitüberschreitung aufgetreten ist und keine Daten geschickt sind.
     * Gibt im Falle eines Poll-Fehlers einen anderen, negativen Fehlercode zurück.
     */
    static int wait(int timeout)
    {
    	int ret = poll(&fds, 1, timeout);
    
    	if (ret < 0) {
    		printk("poll error: %d\n", errno);
    		return -errno;
    	}
    
    	if (ret == 0) {
    		/* Timeout. */
    		return -EAGAIN;
    	}
    
    	if ((fds.revents & POLLERR) == POLLERR) {
    		printk("warte: POLLERR\n");
    		return -EIO;
    	}
    
    	if ((fds.revents & POLLNVAL) == POLLNVAL) {
    		printk("warte: POLLNVAL\n");
    		return -EBADF;
    	}
    
    	if ((fds.revents & POLLIN) != POLLIN) {
    		return -EAGAIN;
    	}
    
    	return 0;
    }
    
    /*************************************************************************************************************/
    
    void main(void)
    {
            cJSON_Init();
            
            int64_t next_msg_time = CONFIG_DATA_UPLOAD_FREQUENCY_MS;
    	int err;
    
    	printk(" Coap/dtls startet.....\n");
    
            // DTLS wird initialisiert
            err = dtls_init();
            if (err<0) {
              printk("DTLS Init Error: %d\n", err);
            }else{
              printk("Sicherheitsanmeldeinformationen im Modem bereitgestellt \n");
            };
    
            // Initialisiere das Benutzeroberflächenmodul
            ui_init(ui_evt_handler);
    
            // Modem wird konfiguriert
    #if defined(CONFIG_NRF_MODEM_LIB)
                 
    	modem_konfigurieren();
    
    	k_sem_take(&lte_verbunden, K_FOREVER);
    #endif
    
          next_msg_time = k_uptime_get();
    
            // Verbindungsaufbau zu dem Server
    	err = server_initialisieren();
    	if (err) {
    		printk("Serververbindung kann nicht initialisiert werden\n");
    		return;
    	}
            
            // DTLS Handshake + Verbindung zum Server herstellen
    	err = server_verbinden();
    	if (err) {
    		printk("Keine Verbindung zum Server möglich\n");
    		return;
    	}
    
    while (1) {
    
    		if (k_uptime_get() >= next_msg_time) {
                            
    			if (uebertragung_zu_server_fn()!= 0) {
    				printk("Fehler beim Senden der Anfrage, exit...\n");
    				break;
    			}
    
    			next_msg_time += CONFIG_DATA_UPLOAD_FREQUENCY_MS;
    		}
    
    		int64_t remaining = next_msg_time - k_uptime_get();
    
    		if (remaining < 0) {
    			remaining = 0;
    		}
    
    		err = wait(remaining);
    		if (err < 0) {
    			if (err == -EAGAIN) {
    				continue;
    			}
    
    			printk("Poll error, exit...\n");
    			break;
    		}
    
                    
    	}
    
    }
    

    I set the timer() at the position where i want a delay to be able to know when and what is coming as next.

    Any idea, if actually that which i am doing the best approach is? What do you think?

    Best regards,

    Cedric

  • ced27 said:
    couldn't trace the timer actually working when looking at the Graph

    What do you mean by this? Do you see "Expiry function is running" in the terminal? If you do see that, the timer is indeed working.

    ced27 said:

    I set the timer() at the position where i want a delay to be able to know when and what is coming as next.

    Any idea, if actually that which i am doing the best approach is? What do you think?

    If you want to use a timer to execute stuff at regular intervals, I would recommend you to set it up as I did in my sample. Then use k_sem_give() inside the expiry function and k_sem_take() inside a while(true) loop and execute the stuff you want, like I've done here. Another approach is to use work queues, and offload the work from the expiry function to a work queue thread.

    Best regards,

    Simon

Related