DS1338 i2c Read issue - linux

Hi I'm trying read the time from RTC-DS1338 with my linux Single Board Computer, but there is a problem with my code. I'm reading bad outputs with it.
I tried to read with i2cget -y 0 0x68 0 it works. but my code does not.
Can anybody help me ?
#include <stdio.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <errno.h>
#define I2C_ADDR 0x68
int main (void)
{
char value;
int fd;
unsigned char pData[10];
char i;
if ((fd = open("/dev/i2c-0", O_RDWR)) < 0)
{
printf("Error: Couldn't open device! %d\n", fd);
return 1;
}
if (ioctl(fd, I2C_SLAVE, I2C_ADDR) < 0)
{
printf("Error: Couldn't find device on address!\n");
return 1;
}
while (1)
{
if (read(fd, &pData, 4) != 4)
{
perror("Read conversion");
}
else
{
for(i=0;i<4;i++) printf(" %02x ",(pData[i] & 0xFF));
printf("\n");
}
sleep(2);
}
return 0;
}
Bad Output:
00 b3 49 47
4e 27 09 21
24 81 29 00
1a 20 02 10
16 1e 1a 46
1a 00 96 18
45 82 03 e0
24 40 88 1c
Good Data:
00 05 08 00
01 05 08 00
02 05 08 00
03 05 08 00
04 05 08 00
05 05 08 00

I have resolve my problem with the below code
if ((fd = open("/dev/i2c-0", O_RDWR)) < 0)
{
printf("Error: Couldn't open device! %d\n", fd);
return 1;
}
if (ioctl(fd, I2C_SLAVE, I2C_ADDR) < 0)
{
printf("Error: Couldn't find device on address!\n");
return 1;
}
if (write(fd, wData, 1) != 1)
{
perror("Write to register");
}
if (read(fd, rData, 64) != 64)
{
perror("Read conversion");
}
else
{
memcpy(Dat,rData,7);
}
close(fd);
return 0;

Related

Decompressing data received as binary data in lambda - incorrect header check

I want to send compressed data (gzip) to some URL that will trigger a (proxy) lambda function, that will decompress the data.
The lambda function (NodeJS 8):
let zlib = require('zlib');
exports.handler = async (event) => {
let decompressedData = zlib.gunzipSync(event['body'])
return {
"statusCode": 200,
"body": decompressedData.toString()
};
};
I trigger it with a curl command to the URL (through API gateway), for some file that I compressed example.gz with gzip:
curl -X POST --data-binary #example.gz https://URL...
As a result, I get:
{"message": "Internal server error"}
And the error is (logs in Cloudwatch):
"errorMessage": "incorrect header check",
"errorType": "Error",
"stackTrace": [
"Gunzip.zlibOnError (zlib.js:153:15)",
"Gunzip._processChunk (zlib.js:411:30)",
"zlibBufferSync (zlib.js:144:38)",
"Object.gunzipSync (zlib.js:590:14)",
"exports.handler (/var/task/test_index.js:5:33)"
]
When I looked at the event['body'] itself, I see the exact data as I see in example.gz. Perhaps I need some special header? I just want to pass the data as is.
as Michael - sqlbot said, By default, API Gateway can't pass binary data into a Lambda function.
What worked for me:
I added the header Content-Type: application/octet-stream in the curl command, and in the API gateway settings, on Binary Media Types I added application/octet-stream.
This way, the data is passed in base64, and afterwards I just converted the date that is in base64 to a buffer:
let data = Buffer.from(event['body'], "base64")
And afterwards just decompress it.
For more information read here
1/ First you need to build your gzip correctly, ensure that gzip file header is not present : curl command a gzipped POST body to an apache server
Wrong way :
echo '{ "mydummy" : "json" }' > body
gzip body
hexdump -C body.gz
00000000 1f 8b 08 08 20 08 30 59 00 03 62 6f 64 79 00 ab |.... .0Y..body..|
00000010 56 50 ca ad 4c 29 cd cd ad 54 52 b0 52 50 ca 2a |VP..L)...TR.RP.*|
00000020 ce cf 53 52 a8 e5 02 00 a6 6a 24 99 17 00 00 00 |..SR.....j$.....|
00000030
Good way :
echo '{ "mydummy" : "json" }' | gzip > body.gz
hexdump -C body.gz
00000000 1f 8b 08 00 08 0a 30 59 00 03 ab 56 50 ca ad 4c |......0Y...VP..L|
00000010 29 cd cd ad 54 52 b0 52 50 ca 2a ce cf 53 52 a8 |)...TR.RP.*..SR.|
00000020 e5 02 00 a6 6a 24 99 17 00 00 00 |....j$.....|
0000002b
2/ In curl don't forget to specify the content-encoding with
-H "Content-Encoding: gzip"
3/ In addition if you use express+compress you don't need to call zlib
curl -X POST "http://example.org/api/a" -H "Content-Encoding: gzip" -H "Content-Type: application/json" --data-binary #body.gz
router.post("/api/a", function(req, res){
console.log(req.body); // { mydummy: 'json' }
});

Output matched string through end of tab-indented section?

Sample code from pci.ids below. I want to use the class code from lspci (lets say it's 0580) and have it navigate to C 05 > 80: Memory controller. I feel the most appropriate way (to avoid returning a value from the wrong class) is to just cut the section of C 05 first, then look for 80. Grep -A... will return everything after, and therefore if the 80 doesn't match something in C05 it would jump down to some Cn which contains an 80 element.
C 03 Display controller
00 VGA compatible controller
00 VGA controller
01 8514 controller
01 XGA compatible controller
02 3D controller
80 Display controller
C 04 Multimedia controller
00 Multimedia video controller
01 Multimedia audio controller
02 Computer telephony device
03 Audio device
80 Multimedia controller
C 05 Memory controller
00 RAM memory
01 FLASH memory
80 Memory controller
C 06 Bridge
00 Host bridge
01 ISA bridge
02 EISA bridge
03 MicroChannel bridge
04 PCI bridge
00 Normal decode
01 Subtractive decode
05 PCMCIA bridge
To pass "0580" into the awk program:
awk -v value='0580' '
BEGIN {a = substr(value,1,2); b = substr(value,3,2)}
$1 == "C" { p = ($2 == a)}
p && $1 == b {print; exit}
' file
If the first word is "C", set a boolean to true if the second word is "05".
If the flag is true and the first word is "80", print the current line and exit.

Linux Kernel : Not able to load simple linux kernel module with workqueues

I'm having an issue with using the workqueues in my linux kernel module.
My modules compiles without giving any error but at the time of loading it fails.
I'm not able to load the following module and getting following error in dmesg.
[root#nanderson test_mod]# insmod workqueue_test.ko
insmod: ERROR: could not insert module workqueue_test.ko: Unknown symbol in module
[root#nanderson test_mod]# dmesg -c
[50404.453417] workqueue_test: Unknown symbol destroy_workqueue (err 0)
[50404.453437] workqueue_test: Unknown symbol __alloc_workqueue_key (err 0)
[root#nanderson test_mod]#
Following is the module code :-
1 #include <linux/module.h>
2 #include <linux/kernel.h>
3 #include <linux/kthread.h>
4 #include <linux/blkdev.h>
5 #include <linux/fs.h>
6 #include <linux/delay.h>
7 #include <linux/workqueue.h>
8 #include <linux/completion.h>
9
10
11 #define LOG_ENTRY() \
12 do {\
13 printk(KERN_INFO "++ %s %d %s\n", __func__, __LINE__,\
14 current->comm);\
15 } while (0);
16
17 #define LOG_INFO() \
18 do {\
19 printk(KERN_INFO "%s %d %s\n", __func__, __LINE__,\
20 current->comm); mdelay(1000);\
21 } while (0);
22
23 #define LOG_EXIT() \
24 do {\
25 printk(KERN_INFO "-- %s %d %s\n", __func__, __LINE__,\
26 current->comm);\
27 } while (0);
28
29
30 void
31 async_callback(void *data)
32 {
33
34 }
35
36 int
37 init_module(void)
38 {
39 struct workqueue_struct *async_queue;
40
41 LOG_ENTRY();
42 if ((async_queue = create_workqueue("HGST_WORKQUEUE")) == NULL) {
43 printk(KERN_ERR "failed to create workqueue\n");
44 return -1;
45 }
46
47 mdelay(10000);
48 destroy_workqueue(async_queue);
49 LOG_EXIT();
50 return 0;
51 }
52
53
54 void
55 cleanup_module(void)
56 {
57 printk(KERN_INFO "Unloading MOdule..\n");
58 }
I also looked into /proc/kallsysm for the unknown symbols reposted by insmod looks like symbols are available following is the output:-
[root#nanderson test_mod]# cat /proc/kallsyms | grep __alloc_workqueue_key
ffffffff81084a10 T __alloc_workqueue_key
ffffffff8187a090 r __ksymtab___alloc_workqueue_key
ffffffff8188bd70 r __kcrctab___alloc_workqueue_key
ffffffff81892ba0 r __kstrtab___alloc_workqueue_key
[root#nanderson test_mod]#
Can someone tell me what might be the problem or I'm missing something ?
Thanks.
You need
MODULE_LICENSE("GPL");
in you code for use GPL symbols (exported using EXPORT_SYMBOL_GPL).
Otherwise module loader simply does not see such symbols.

Issues regarding mutexes on POSIX threads

I'm having some issues with the following code. I just can't seem to find the bug:
1 #include <pthread.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5
6 struct bla
7 {
8 pthread_mutex_t mut;
9 int x;
10 };
11
12
13 pthread_t tid;
14
15 void *thr_fn1 (struct bla *fp);
16
17 int main()
18 {
19 struct bla *fp;
20 fp = (struct bla *) malloc (sizeof(struct bla));
21 fp->x=3;
22 printf ("Initializing mutex_init\n");
23 pthread_mutex_init (&fp->mut,NULL);
24 pthread_create (&tid,NULL,thr_fn1,fp);
25 sleep (2);
26 printf ("Main thread ended sleep. Incrementing.\n");
27 fp->x++;
28 pthread_join (tid,NULL);
29 printf ("x=%d\n",fp->x);
30 pthread_mutex_destroy(&fp->mut);
31 return 0;
32
33 }
34
35 void *thr_fn1 (struct bla *fp)
36 {
37 printf ("Locking new thread!\n");
38 pthread_mutex_lock (&fp->mut);
39 printf ("Sleeping.\n");
40 sleep (5);
41 pthread_mutex_unlock (&fp->mut);
42 printf ("Thread unlocked.\n");
43 return ((void *) 0);
44 }
Why does the value still get incremented at line 27? Shouldn't it be protected by the mutex in the second thread by the lock (line 38)?
Thanks!
There is no automatic association between mutexes and data. If you want a mutex to protect some particular set of data, you are responsible for locking and unlocking the mutex around accesses to that data:
sleep (2);
pthread_mutex_lock(&fp->mut);
printf ("Main thread ended sleep. Incrementing.\n");
fp->x++;
pthread_mutex_unlock(&fp->mut);

Create a ethernet packet in a kernel module and send it

I need to create an ethernet packet an send it in my kernel module. Someone can help me to do this?
I think i need to create a skb using dev_alloc_skb, then i need to write the mac_ethernet, insert the data and send it using dev_queu_xmit.
But i'm not sure if this work, or if it is the right and easiest way to do it.
Best Regards
EDIT1:
int sendpacket ()
{
unsigned char dest[ETH_ALEN]={0x00,0x25,0x22,0x05,0xF3,0xF0};
unsigned char src[ETH_ALEN] = {0x90,0xE6,0xBA,0x48,0x7C,0x87};
struct sk_buff * skbt =alloc_skb(ETH_FRAME_LEN,GFP_KERNEL);
//skb_reserve(skb,ETH_FRAME_LEN);
dev_hard_header(skbt,dev_eth1,ETH_P_802_3,dest,src,dev_eth1->addr_len);
if(dev_queue_xmit(skbt)!=NET_XMIT_SUCCESS)
{
printk("Not send!!\n");
}
kfree_skb(skbt);
return 0;
}
> Dmesg command:
>
> 677.826933] Hello:I'm the hook module!!!! [ 677.826937] 2!!!! [ 677.826941] skb_under_panic: text:c0723608 len:14 put:14 head:f1843800 data:f18437f2 tail:0xf1843800 end:0xf1843e00 dev:<NULL> [ 677.826959]
> ------------[ cut here ]------------ [ 677.826961] kernel BUG at net/core/skbuff.c:146! [ 677.826964] invalid opcode: 0000 [#1] SMP [
> 677.826967] last sysfs file: /sys/devices/system/cpu/cpu1/cache/index2/shared_cpu_map [
> 677.826969] Modules linked in: sendpacket(+) bluetooth rfkill vfat fat fuse sunrpc cpufreq_ondemand acpi_cpufreq mperf ip6t_REJECT
> nf_conntrack_ipv6 ip6table_filter ip6_tables ipv6 uinput
> snd_hda_codec_atihdmi snd_hda_codec_realtek snd_hda_intel
> snd_hda_codec snd_hwdep snd_seq snd_seq_device snd_pcm snd_timer snd
> soundcore atl1e snd_page_alloc iTCO_wdt iTCO_vendor_support r8169 mii
> i2c_i801 microcode asus_atk0110 pcspkr ata_generic pata_acpi
> usb_storage pata_marvell radeon ttm drm_kms_helper drm i2c_algo_bit
> i2c_core [last unloaded: sendpacket] [ 677.827003] [ 677.827003]
> Pid: 4780, comm: insmod Tainted: G W 2.6.35101 #7 P5QL
> PRO/P5QL PRO [ 677.827003] EIP: 0060:[<c070a192>] EFLAGS: 00210246
> CPU: 0 [ 677.827003] EIP is at skb_push+0x57/0x62 [ 677.827003] EAX:
> 00000088 EBX: c08f9fdc ECX: f156bf10 EDX: c093b4ca [ 677.827003] ESI:
> 00000000 EDI: f51ca000 EBP: f156bf38 ESP: f156bf0c [ 677.827003] DS:
> 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 [ 677.827003] Process insmod
> (pid: 4780, ti=f156a000 task=f2b071a0 task.ti=f156a000) [ 677.827003]
> Stack: [ 677.827003] c093b4ca c0723608 0000000e 0000000e f1843800
> f18437f2 f1843800 f1843e00 [ 677.827003] <0> c08f9fdc f156bf64
> f156bf6a f156bf50 c0723608 00000001 c07235e5 f3b6c000 [ 677.827003]
> <0> 00835ff4 f156bf78 f7d640a8 f156bf6a f156bf64 00000006 48bae690
> 2500877c [ 677.827003] Call Trace: [ 677.827003] [<c0723608>] ?
> eth_header+0x23/0x93 [ 677.827003] [<c0723608>] ?
> eth_header+0x23/0x93 [ 677.827003] [<c07235e5>] ?
> eth_header+0x0/0x93 [ 677.827003] [<f7d640a8>] ?
> sendpacket+0x8f/0xb6 [sendpacket] [ 677.827003] [<f7d67000>] ?
> hook_init+0x0/0x46 [sendpacket] [ 677.827003] [<f7d67044>] ?
> hook_init+0x44/0x46 [sendpacket] [ 677.827003] [<c0401246>] ?
> do_one_initcall+0x4f/0x139 [ 677.827003] [<c0451e29>] ?
> blocking_notifier_call_chain+0x11/0x13 [ 677.827003] [<c046210c>] ?
> sys_init_module+0x7f/0x19b [ 677.827003] [<c040321f>] ?
> sysenter_do_call+0x12/0x28 [ 677.827003] Code: c0 85 f6 0f 45 de 53
> ff b0 a8 00 00 00 ff b0 a4 00 00 00 51 ff b0 ac 00 00 00 52 ff 70 50
> ff 75 04 68 ca b4 93 c0 e8 ad 4a 09 00 <0f> 0b 8d 65 f8 89 c8 5b 5e 5d
> c3 55 89 e5 56 53 0f 1f 44 00 00 [ 677.827116] EIP: [<c070a192>]
> skb_push+0x57/0x62 SS:ESP 0068:f156bf0c [ 677.827154] ---[ end trace
> dee1e3278503a581 ]---
In your case you just want to use raw packets from user space instead of dealing with the complexities of kernel code.
This blog post details how to do everything you need.
At the risk of sounding like a broken record you're learning why this should be done from user space.
Because you seem determined to make this mistake anyway, let's try to figure out what the problem is.
It's also a good illustration of how helpful it is to have source code. The exception log tells you the problem occurred on line 146 of net/core/skbuff.c.
That's within the function skb_under_panic(), which is only used in that file (it's static after all), from within skb_push().
The skb_push() function expands the skb forwards. Basically it creates room in the buffer for a new header. It does this by shifting the internal data pointer forward.
In your case, the internal data pointer is still in its original localtion: at the very from of the skb. You need to reserve some room at the front of the skb first. Use skb_reserve(), pretty much just like you had. Why did you comment that out?
Also, you need to check that the allocation of the skb succeeded. Kernel allocators can (and do) return NULL sometimes.

Resources