Closed junwushi closed 3 years ago
can open CONFIG_HZ option in kernel?
Hi, Maybe enable high resolution timer? Setting a higher HZ on a 300MHz CPU system might not be a very good option. The scheduler executed too frequent and the overhead can actually slow down the system.
Thank you for your suggestion. I'll use etimer0 for timing. I want to know whether the operation of reading the value of etimer is thread safe. If I try to lock, it will nest with another lock in the function calling getticks, which will easily lead to deadlock. See function below.
static volatile int efd = -1; const char devetimer[] = "/dev/etimer0"; //timeout=1000 1ms =1000000 1s int init_etimer(int timeout) { int tm; if (timeout == 0) tm = 1000; else tm = timeout; ETIMER_LOCK ; efd = open(&devetimer[0], O_RDWR); if (efd < 0) { ETIMER_UNLOCK ; //LOGERR("open etimer %d error\n", 0); return -1; } //switch clock 12MHz ioctl(efd, ETMR_IOC_CLKHXT, NULL); //Periodic demo ioctl(efd, ETMR_IOC_PERIODIC, &tm); ETIMER_UNLOCK ; return efd; }
uint64_t getticks(void) { static unsigned int tick_h = 0U; static unsigned int tick_l = 0U; unsigned int tick; uint64_t retticks; ETIMER_LOCK ; if (efd < 0) { ETIMER_UNLOCK ; return 0; } read(efd, &tick, sizeof(tick)); ; if (tick < tick_l) { tick_h++; } tick_l = tick; retticks = (((uint64_t) tick_h << 24) | tick_l); ETIMER_UNLOCK ; return retticks; } void uninit_etimer(void) { ETIMER_LOCK ; if (efd < 0) { ETIMER_UNLOCK ; return; } ioctl(efd, ETMR_IOC_STOP, NULL); close(efd); efd = -1; ETIMER_UNLOCK ; }
Hi, There's already a spinlock with in the driver's read function. You don't need add an application level lock for protection.
static ssize_t etimer_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
unsigned long flag;
struct nuc970_etimer *t = (struct nuc970_etimer *)filp->private_data;
int ret = 0;
spin_lock_irqsave(&t->lock, flag);
After I remove the lock, I run my program, and then Ctrl + C exits several times. I confirm that each exit will execute uninit eimer function, do this many times, and then run the program will find that the etimer device can not be opened, the error show "init etimer fail."。 There is no exact reason to be found now.
Hi, What's the error code?
[root 02:17 ~]# cat /dev/etimer0 cat: can't open '/dev/etimer0': Device or resource busy [root 02:17 ~]#
I add debugging information to the driver. When I execute the following two statements ioctl(efd, ETMR IOC STOP, NULL); close(efd); Etimer_release in kernel function has not been called. Why?
1.add debug message in driver static int etimer_release(struct inode inode, struct file filp) { struct nuc970_etimer t = (struct nuc970_etimer )filp->private_data; int ch = t->ch; unsigned long flag; printk("etimer%d closed1.\n",ch);
stop_timer(t);
**printk("etimer%d closed2.\n",ch);**
// free irq
free_irq(etmr[ch]->irq, etmr[ch]);
// disable clk
clk_disable(etmr[ch]->clk);
clk_disable(etmr[ch]->eclk);
clk_put(etmr[ch]->clk);
clk_put(etmr[ch]->eclk);
**printk("etimer%d closed3.\n",ch);**
spin_lock_irqsave(&etmr[ch]->lock, flag);
etmr[ch]->occupied = 0;
spin_unlock_irqrestore(&etmr[ch]->lock, flag);
filp->private_data = NULL;
**printk("etimer%d closed4.\n",ch);**
return(0);
}
2.program running once, it is working well. Starting router: OK [ 29.980000] etimer0 opened.
Welcome to FTGateway FTGateway login: [ 30.010000] ttyS3: 1 input overrun(s) root Password: [root 07:54 ~]# killall router [root 07:54 ~]# [ 42.680000] etimer0 closed1. [ 42.680000] etimer0 closed2. [ 42.690000] etimer0 closed3. [ 42.690000] etimer0 closed4.
3.program running seconds, failing:
[root 07:54 ~]# router -b460800
FT-RF Router V1.18 Runn[ 47.630000] etimer0 opened. ing at: libpcap version 1.10.0 (with TPACKET_V3) RF baudrate:460800 RF device:ttyS5 WAN device:tap0 BAT Voltage:4194mv AC Voltage:5689mv Packet interval(0-20000us):0 Packet EOF number(0xc0)(0-10):2 2021-07-02 07:54:40.840 :etimer open it 3. udhcpc: started, v1.25.1 udhcpc: sending discover udhcpc: sending select for 192.168.0.93 udhcpc: lease of 192.168.0.93 obtained, lease time 691200 2021-07-02 07:54:41.590 :libnet_init tap0 fail:libnet_check_iface() ioctl: No such device waiting 5 seconds try again. ^C 2021-07-02 07:54:48.080 :etimer close it 3. 4.---->"print by user application ,but no kernal closed message output " "
void get_time_stamp(char *timestamp) {
}
result: 2021-06-26 07:05:17.930000:---->Received Wlan Packet No.: 1 size:86 caplen:86 2021-06-26 07:05:17.930000:ETH Payload: 2021-06-26 07:05:17.930000:Ehternet II: 2021-06-26 07:05:17.950000:------->got a signal 2021-06-26 07:05:17.950000: fe 80 00 00 00 00 00 00 52 57 9c ff fe aa 06 ba 2021-06-26 07:05:17.950000: fe 80 00 00 00 00 00 00 d4 08 67 ff fe cf b1 a5 2021-06-26 07:05:17.950000:fe80::5257:9cff:feaa:6ba is not belong this network 2021-06-26 07:05:17.950000: 33 33 ff aa 06 ba 00 ff 9b 15 13 16 86 dd 2021-06-26 07:05:17.950000:Frame type: 0x86dd 2021-06-26 07:05:17.950000:Source:00:ff:9b:15:13:16 2021-06-26 07:05:17.950000:Destination:33:33:ff:aa:06:ba
how can impove the resolution of struct timeval ‘s tv_usec。
i want change tick define in the time.c from #define TICKS_PER_SEC 100 to #define TICKS_PER_SEC 1000 Is it possible? Is there any bad influence?